diff options
Diffstat (limited to 'webrtc/modules/media_file/source')
-rw-r--r-- | webrtc/modules/media_file/source/OWNERS | 5 | ||||
-rw-r--r-- | webrtc/modules/media_file/source/media_file_impl.cc | 1137 | ||||
-rw-r--r-- | webrtc/modules/media_file/source/media_file_impl.h | 148 | ||||
-rw-r--r-- | webrtc/modules/media_file/source/media_file_unittest.cc | 96 | ||||
-rw-r--r-- | webrtc/modules/media_file/source/media_file_utility.cc | 1656 | ||||
-rw-r--r-- | webrtc/modules/media_file/source/media_file_utility.h | 284 |
6 files changed, 0 insertions, 3326 deletions
diff --git a/webrtc/modules/media_file/source/OWNERS b/webrtc/modules/media_file/source/OWNERS deleted file mode 100644 index 3ee6b4bf5f..0000000000 --- a/webrtc/modules/media_file/source/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ - -# These are for the common case of adding or renaming files. If you're doing -# structural changes, please get a review from a reviewer in this file. -per-file *.gyp=* -per-file *.gypi=* diff --git a/webrtc/modules/media_file/source/media_file_impl.cc b/webrtc/modules/media_file/source/media_file_impl.cc deleted file mode 100644 index 50175b86d5..0000000000 --- a/webrtc/modules/media_file/source/media_file_impl.cc +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <assert.h> - -#include "webrtc/base/format_macros.h" -#include "webrtc/modules/media_file/source/media_file_impl.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/system_wrappers/include/file_wrapper.h" -#include "webrtc/system_wrappers/include/tick_util.h" -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { -MediaFile* MediaFile::CreateMediaFile(const int32_t id) -{ - return new MediaFileImpl(id); -} - -void MediaFile::DestroyMediaFile(MediaFile* module) -{ - delete static_cast<MediaFileImpl*>(module); -} - -MediaFileImpl::MediaFileImpl(const int32_t id) - : _id(id), - _crit(CriticalSectionWrapper::CreateCriticalSection()), - _callbackCrit(CriticalSectionWrapper::CreateCriticalSection()), - _ptrFileUtilityObj(NULL), - codec_info_(), - _ptrInStream(NULL), - _ptrOutStream(NULL), - _fileFormat((FileFormats)-1), - _recordDurationMs(0), - _playoutPositionMs(0), - _notificationMs(0), - _playingActive(false), - _recordingActive(false), - _isStereo(false), - _openFile(false), - _fileName(), - _ptrCallback(NULL) -{ - WEBRTC_TRACE(kTraceMemory, kTraceFile, id, "Created"); - - codec_info_.plname[0] = '\0'; - _fileName[0] = '\0'; -} - - -MediaFileImpl::~MediaFileImpl() -{ - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, "~MediaFileImpl()"); - { - CriticalSectionScoped lock(_crit); - - if(_playingActive) - { - StopPlaying(); - } - - if(_recordingActive) - { - StopRecording(); - } - - delete _ptrFileUtilityObj; - - if(_openFile) - { - delete _ptrInStream; - _ptrInStream = NULL; - delete _ptrOutStream; - _ptrOutStream = NULL; - } - } - - delete _crit; - delete _callbackCrit; -} - -int64_t MediaFileImpl::TimeUntilNextProcess() -{ - WEBRTC_TRACE( - kTraceWarning, - kTraceFile, - _id, - "TimeUntilNextProcess: This method is not used by MediaFile class."); - return -1; -} - -int32_t MediaFileImpl::Process() -{ - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "Process: This method is not used by MediaFile class."); - return -1; -} - -int32_t MediaFileImpl::PlayoutAudioData(int8_t* buffer, - size_t& dataLengthInBytes) -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, - "MediaFileImpl::PlayoutData(buffer= 0x%x, bufLen= %" PRIuS ")", - buffer, dataLengthInBytes); - - const size_t bufferLengthInBytes = dataLengthInBytes; - dataLengthInBytes = 0; - - if(buffer == NULL || bufferLengthInBytes == 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Buffer pointer or length is NULL!"); - return -1; - } - - int32_t bytesRead = 0; - { - CriticalSectionScoped lock(_crit); - - if(!_playingActive) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "Not currently playing!"); - return -1; - } - - if(!_ptrFileUtilityObj) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Playing, but no FileUtility object!"); - StopPlaying(); - return -1; - } - - switch(_fileFormat) - { - case kFileFormatPcm32kHzFile: - case kFileFormatPcm16kHzFile: - case kFileFormatPcm8kHzFile: - bytesRead = _ptrFileUtilityObj->ReadPCMData( - *_ptrInStream, - buffer, - bufferLengthInBytes); - break; - case kFileFormatCompressedFile: - bytesRead = _ptrFileUtilityObj->ReadCompressedData( - *_ptrInStream, - buffer, - bufferLengthInBytes); - break; - case kFileFormatWavFile: - bytesRead = _ptrFileUtilityObj->ReadWavDataAsMono( - *_ptrInStream, - buffer, - bufferLengthInBytes); - break; - case kFileFormatPreencodedFile: - bytesRead = _ptrFileUtilityObj->ReadPreEncodedData( - *_ptrInStream, - buffer, - bufferLengthInBytes); - if(bytesRead > 0) - { - dataLengthInBytes = static_cast<size_t>(bytesRead); - return 0; - } - break; - default: - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Invalid file format: %d", _fileFormat); - assert(false); - break; - } - } - - if( bytesRead > 0) - { - dataLengthInBytes = static_cast<size_t>(bytesRead); - } - } - HandlePlayCallbacks(bytesRead); - return 0; -} - -void MediaFileImpl::HandlePlayCallbacks(int32_t bytesRead) -{ - bool playEnded = false; - uint32_t callbackNotifyMs = 0; - - if(bytesRead > 0) - { - // Check if it's time for PlayNotification(..). - _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs(); - if(_notificationMs) - { - if(_playoutPositionMs >= _notificationMs) - { - _notificationMs = 0; - callbackNotifyMs = _playoutPositionMs; - } - } - } - else - { - // If no bytes were read assume end of file. - StopPlaying(); - playEnded = true; - } - - // Only _callbackCrit may and should be taken when making callbacks. - CriticalSectionScoped lock(_callbackCrit); - if(_ptrCallback) - { - if(callbackNotifyMs) - { - _ptrCallback->PlayNotification(_id, callbackNotifyMs); - } - if(playEnded) - { - _ptrCallback->PlayFileEnded(_id); - } - } -} - -int32_t MediaFileImpl::PlayoutStereoData( - int8_t* bufferLeft, - int8_t* bufferRight, - size_t& dataLengthInBytes) -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, - "MediaFileImpl::PlayoutStereoData(Left = 0x%x, Right = 0x%x," - " Len= %" PRIuS ")", - bufferLeft, - bufferRight, - dataLengthInBytes); - - const size_t bufferLengthInBytes = dataLengthInBytes; - dataLengthInBytes = 0; - - if(bufferLeft == NULL || bufferRight == NULL || bufferLengthInBytes == 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "A buffer pointer or the length is NULL!"); - return -1; - } - - bool playEnded = false; - uint32_t callbackNotifyMs = 0; - { - CriticalSectionScoped lock(_crit); - - if(!_playingActive || !_isStereo) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "Not currently playing stereo!"); - return -1; - } - - if(!_ptrFileUtilityObj) - { - WEBRTC_TRACE( - kTraceError, - kTraceFile, - _id, - "Playing stereo, but the FileUtility objects is NULL!"); - StopPlaying(); - return -1; - } - - // Stereo playout only supported for WAV files. - int32_t bytesRead = 0; - switch(_fileFormat) - { - case kFileFormatWavFile: - bytesRead = _ptrFileUtilityObj->ReadWavDataAsStereo( - *_ptrInStream, - bufferLeft, - bufferRight, - bufferLengthInBytes); - break; - default: - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Trying to read non-WAV as stereo audio\ - (not supported)"); - break; - } - - if(bytesRead > 0) - { - dataLengthInBytes = static_cast<size_t>(bytesRead); - - // Check if it's time for PlayNotification(..). - _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs(); - if(_notificationMs) - { - if(_playoutPositionMs >= _notificationMs) - { - _notificationMs = 0; - callbackNotifyMs = _playoutPositionMs; - } - } - } - else - { - // If no bytes were read assume end of file. - StopPlaying(); - playEnded = true; - } - } - - CriticalSectionScoped lock(_callbackCrit); - if(_ptrCallback) - { - if(callbackNotifyMs) - { - _ptrCallback->PlayNotification(_id, callbackNotifyMs); - } - if(playEnded) - { - _ptrCallback->PlayFileEnded(_id); - } - } - return 0; -} - -int32_t MediaFileImpl::StartPlayingAudioFile( - const char* fileName, - const uint32_t notificationTimeMs, - const bool loop, - const FileFormats format, - const CodecInst* codecInst, - const uint32_t startPointMs, - const uint32_t stopPointMs) -{ - if(!ValidFileName(fileName)) - { - return -1; - } - if(!ValidFileFormat(format,codecInst)) - { - return -1; - } - if(!ValidFilePositions(startPointMs,stopPointMs)) - { - return -1; - } - - // Check that the file will play longer than notificationTimeMs ms. - if((startPointMs && stopPointMs && !loop) && - (notificationTimeMs > (stopPointMs - startPointMs))) - { - WEBRTC_TRACE( - kTraceError, - kTraceFile, - _id, - "specified notification time is longer than amount of ms that will\ - be played"); - return -1; - } - - FileWrapper* inputStream = FileWrapper::Create(); - if(inputStream == NULL) - { - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, - "Failed to allocate input stream for file %s", fileName); - return -1; - } - - if(inputStream->OpenFile(fileName, true, loop) != 0) - { - delete inputStream; - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Could not open input file %s", fileName); - return -1; - } - - if(StartPlayingStream(*inputStream, loop, notificationTimeMs, - format, codecInst, startPointMs, stopPointMs) == -1) - { - inputStream->CloseFile(); - delete inputStream; - return -1; - } - - CriticalSectionScoped lock(_crit); - _openFile = true; - strncpy(_fileName, fileName, sizeof(_fileName)); - _fileName[sizeof(_fileName) - 1] = '\0'; - return 0; -} - -int32_t MediaFileImpl::StartPlayingAudioStream( - InStream& stream, - const uint32_t notificationTimeMs, - const FileFormats format, - const CodecInst* codecInst, - const uint32_t startPointMs, - const uint32_t stopPointMs) -{ - return StartPlayingStream(stream, false, notificationTimeMs, format, - codecInst, startPointMs, stopPointMs); -} - -int32_t MediaFileImpl::StartPlayingStream( - InStream& stream, - bool loop, - const uint32_t notificationTimeMs, - const FileFormats format, - const CodecInst* codecInst, - const uint32_t startPointMs, - const uint32_t stopPointMs) -{ - if(!ValidFileFormat(format,codecInst)) - { - return -1; - } - - if(!ValidFilePositions(startPointMs,stopPointMs)) - { - return -1; - } - - CriticalSectionScoped lock(_crit); - if(_playingActive || _recordingActive) - { - WEBRTC_TRACE( - kTraceError, - kTraceFile, - _id, - "StartPlaying called, but already playing or recording file %s", - (_fileName[0] == '\0') ? "(name not set)" : _fileName); - return -1; - } - - if(_ptrFileUtilityObj != NULL) - { - WEBRTC_TRACE(kTraceError, - kTraceFile, - _id, - "StartPlaying called, but FileUtilityObj already exists!"); - StopPlaying(); - return -1; - } - - _ptrFileUtilityObj = new ModuleFileUtility(_id); - if(_ptrFileUtilityObj == NULL) - { - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, - "Failed to create FileUtilityObj!"); - return -1; - } - - switch(format) - { - case kFileFormatWavFile: - { - if(_ptrFileUtilityObj->InitWavReading(stream, startPointMs, - stopPointMs) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Not a valid WAV file!"); - StopPlaying(); - return -1; - } - _fileFormat = kFileFormatWavFile; - break; - } - case kFileFormatCompressedFile: - { - if(_ptrFileUtilityObj->InitCompressedReading(stream, startPointMs, - stopPointMs) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Not a valid Compressed file!"); - StopPlaying(); - return -1; - } - _fileFormat = kFileFormatCompressedFile; - break; - } - case kFileFormatPcm8kHzFile: - case kFileFormatPcm16kHzFile: - case kFileFormatPcm32kHzFile: - { - // ValidFileFormat() called in the beginneing of this function - // prevents codecInst from being NULL here. - assert(codecInst != NULL); - if(!ValidFrequency(codecInst->plfreq) || - _ptrFileUtilityObj->InitPCMReading(stream, startPointMs, - stopPointMs, - codecInst->plfreq) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Not a valid raw 8 or 16 KHz PCM file!"); - StopPlaying(); - return -1; - } - - _fileFormat = format; - break; - } - case kFileFormatPreencodedFile: - { - // ValidFileFormat() called in the beginneing of this function - // prevents codecInst from being NULL here. - assert(codecInst != NULL); - if(_ptrFileUtilityObj->InitPreEncodedReading(stream, *codecInst) == - -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Not a valid PreEncoded file!"); - StopPlaying(); - return -1; - } - - _fileFormat = kFileFormatPreencodedFile; - break; - } - default: - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Invalid file format: %d", format); - assert(false); - break; - } - } - if(_ptrFileUtilityObj->codec_info(codec_info_) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Failed to retrieve codec info!"); - StopPlaying(); - return -1; - } - - _isStereo = (codec_info_.channels == 2); - if(_isStereo && (_fileFormat != kFileFormatWavFile)) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "Stereo is only allowed for WAV files"); - StopPlaying(); - return -1; - } - _playingActive = true; - _playoutPositionMs = _ptrFileUtilityObj->PlayoutPositionMs(); - _ptrInStream = &stream; - _notificationMs = notificationTimeMs; - - return 0; -} - -int32_t MediaFileImpl::StopPlaying() -{ - - CriticalSectionScoped lock(_crit); - _isStereo = false; - if(_ptrFileUtilityObj) - { - delete _ptrFileUtilityObj; - _ptrFileUtilityObj = NULL; - } - if(_ptrInStream) - { - // If MediaFileImpl opened the InStream it must be reclaimed here. - if(_openFile) - { - delete _ptrInStream; - _openFile = false; - } - _ptrInStream = NULL; - } - - codec_info_.pltype = 0; - codec_info_.plname[0] = '\0'; - - if(!_playingActive) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "playing is not active!"); - return -1; - } - - _playingActive = false; - return 0; -} - -bool MediaFileImpl::IsPlaying() -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsPlaying()"); - CriticalSectionScoped lock(_crit); - return _playingActive; -} - -int32_t MediaFileImpl::IncomingAudioData( - const int8_t* buffer, - const size_t bufferLengthInBytes) -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, - "MediaFile::IncomingData(buffer= 0x%x, bufLen= %" PRIuS, - buffer, bufferLengthInBytes); - - if(buffer == NULL || bufferLengthInBytes == 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Buffer pointer or length is NULL!"); - return -1; - } - - bool recordingEnded = false; - uint32_t callbackNotifyMs = 0; - { - CriticalSectionScoped lock(_crit); - - if(!_recordingActive) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "Not currently recording!"); - return -1; - } - if(_ptrOutStream == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Recording is active, but output stream is NULL!"); - assert(false); - return -1; - } - - int32_t bytesWritten = 0; - uint32_t samplesWritten = codec_info_.pacsize; - if(_ptrFileUtilityObj) - { - switch(_fileFormat) - { - case kFileFormatPcm8kHzFile: - case kFileFormatPcm16kHzFile: - case kFileFormatPcm32kHzFile: - bytesWritten = _ptrFileUtilityObj->WritePCMData( - *_ptrOutStream, - buffer, - bufferLengthInBytes); - - // Sample size is 2 bytes. - if(bytesWritten > 0) - { - samplesWritten = bytesWritten/sizeof(int16_t); - } - break; - case kFileFormatCompressedFile: - bytesWritten = _ptrFileUtilityObj->WriteCompressedData( - *_ptrOutStream, buffer, bufferLengthInBytes); - break; - case kFileFormatWavFile: - bytesWritten = _ptrFileUtilityObj->WriteWavData( - *_ptrOutStream, - buffer, - bufferLengthInBytes); - if(bytesWritten > 0 && STR_NCASE_CMP(codec_info_.plname, - "L16", 4) == 0) - { - // Sample size is 2 bytes. - samplesWritten = bytesWritten/sizeof(int16_t); - } - break; - case kFileFormatPreencodedFile: - bytesWritten = _ptrFileUtilityObj->WritePreEncodedData( - *_ptrOutStream, buffer, bufferLengthInBytes); - break; - default: - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Invalid file format: %d", _fileFormat); - assert(false); - break; - } - } else { - // TODO (hellner): quick look at the code makes me think that this - // code is never executed. Remove? - if(_ptrOutStream) - { - if(_ptrOutStream->Write(buffer, bufferLengthInBytes)) - { - bytesWritten = static_cast<int32_t>(bufferLengthInBytes); - } - } - } - - _recordDurationMs += samplesWritten / (codec_info_.plfreq / 1000); - - // Check if it's time for RecordNotification(..). - if(_notificationMs) - { - if(_recordDurationMs >= _notificationMs) - { - _notificationMs = 0; - callbackNotifyMs = _recordDurationMs; - } - } - if(bytesWritten < (int32_t)bufferLengthInBytes) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "Failed to write all requested bytes!"); - StopRecording(); - recordingEnded = true; - } - } - - // Only _callbackCrit may and should be taken when making callbacks. - CriticalSectionScoped lock(_callbackCrit); - if(_ptrCallback) - { - if(callbackNotifyMs) - { - _ptrCallback->RecordNotification(_id, callbackNotifyMs); - } - if(recordingEnded) - { - _ptrCallback->RecordFileEnded(_id); - return -1; - } - } - return 0; -} - -int32_t MediaFileImpl::StartRecordingAudioFile( - const char* fileName, - const FileFormats format, - const CodecInst& codecInst, - const uint32_t notificationTimeMs, - const uint32_t maxSizeBytes) -{ - if(!ValidFileName(fileName)) - { - return -1; - } - if(!ValidFileFormat(format,&codecInst)) - { - return -1; - } - - FileWrapper* outputStream = FileWrapper::Create(); - if(outputStream == NULL) - { - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, - "Failed to allocate memory for output stream"); - return -1; - } - - if(outputStream->OpenFile(fileName, false) != 0) - { - delete outputStream; - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Could not open output file '%s' for writing!", - fileName); - return -1; - } - - if(maxSizeBytes) - { - outputStream->SetMaxFileSize(maxSizeBytes); - } - - if(StartRecordingAudioStream(*outputStream, format, codecInst, - notificationTimeMs) == -1) - { - outputStream->CloseFile(); - delete outputStream; - return -1; - } - - CriticalSectionScoped lock(_crit); - _openFile = true; - strncpy(_fileName, fileName, sizeof(_fileName)); - _fileName[sizeof(_fileName) - 1] = '\0'; - return 0; -} - -int32_t MediaFileImpl::StartRecordingAudioStream( - OutStream& stream, - const FileFormats format, - const CodecInst& codecInst, - const uint32_t notificationTimeMs) -{ - // Check codec info - if(!ValidFileFormat(format,&codecInst)) - { - return -1; - } - - CriticalSectionScoped lock(_crit); - if(_recordingActive || _playingActive) - { - WEBRTC_TRACE( - kTraceError, - kTraceFile, - _id, - "StartRecording called, but already recording or playing file %s!", - _fileName); - return -1; - } - - if(_ptrFileUtilityObj != NULL) - { - WEBRTC_TRACE( - kTraceError, - kTraceFile, - _id, - "StartRecording called, but fileUtilityObj already exists!"); - StopRecording(); - return -1; - } - - _ptrFileUtilityObj = new ModuleFileUtility(_id); - if(_ptrFileUtilityObj == NULL) - { - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, - "Cannot allocate fileUtilityObj!"); - return -1; - } - - CodecInst tmpAudioCodec; - memcpy(&tmpAudioCodec, &codecInst, sizeof(CodecInst)); - switch(format) - { - case kFileFormatWavFile: - { - if(_ptrFileUtilityObj->InitWavWriting(stream, codecInst) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Failed to initialize WAV file!"); - delete _ptrFileUtilityObj; - _ptrFileUtilityObj = NULL; - return -1; - } - _fileFormat = kFileFormatWavFile; - break; - } - case kFileFormatCompressedFile: - { - // Write compression codec name at beginning of file - if(_ptrFileUtilityObj->InitCompressedWriting(stream, codecInst) == - -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Failed to initialize Compressed file!"); - delete _ptrFileUtilityObj; - _ptrFileUtilityObj = NULL; - return -1; - } - _fileFormat = kFileFormatCompressedFile; - break; - } - case kFileFormatPcm8kHzFile: - case kFileFormatPcm16kHzFile: - { - if(!ValidFrequency(codecInst.plfreq) || - _ptrFileUtilityObj->InitPCMWriting(stream, codecInst.plfreq) == - -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Failed to initialize 8 or 16KHz PCM file!"); - delete _ptrFileUtilityObj; - _ptrFileUtilityObj = NULL; - return -1; - } - _fileFormat = format; - break; - } - case kFileFormatPreencodedFile: - { - if(_ptrFileUtilityObj->InitPreEncodedWriting(stream, codecInst) == - -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Failed to initialize Pre-Encoded file!"); - delete _ptrFileUtilityObj; - _ptrFileUtilityObj = NULL; - return -1; - } - - _fileFormat = kFileFormatPreencodedFile; - break; - } - default: - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Invalid file format %d specified!", format); - delete _ptrFileUtilityObj; - _ptrFileUtilityObj = NULL; - return -1; - } - } - _isStereo = (tmpAudioCodec.channels == 2); - if(_isStereo) - { - if(_fileFormat != kFileFormatWavFile) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "Stereo is only allowed for WAV files"); - StopRecording(); - return -1; - } - if((STR_NCASE_CMP(tmpAudioCodec.plname, "L16", 4) != 0) && - (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMU", 5) != 0) && - (STR_NCASE_CMP(tmpAudioCodec.plname, "PCMA", 5) != 0)) - { - WEBRTC_TRACE( - kTraceWarning, - kTraceFile, - _id, - "Stereo is only allowed for codec PCMU, PCMA and L16 "); - StopRecording(); - return -1; - } - } - memcpy(&codec_info_, &tmpAudioCodec, sizeof(CodecInst)); - _recordingActive = true; - _ptrOutStream = &stream; - _notificationMs = notificationTimeMs; - _recordDurationMs = 0; - return 0; -} - -int32_t MediaFileImpl::StopRecording() -{ - - CriticalSectionScoped lock(_crit); - if(!_recordingActive) - { - WEBRTC_TRACE(kTraceWarning, kTraceFile, _id, - "recording is not active!"); - return -1; - } - - _isStereo = false; - - if(_ptrFileUtilityObj != NULL) - { - // Both AVI and WAV header has to be updated before closing the stream - // because they contain size information. - if((_fileFormat == kFileFormatWavFile) && - (_ptrOutStream != NULL)) - { - _ptrFileUtilityObj->UpdateWavHeader(*_ptrOutStream); - } - delete _ptrFileUtilityObj; - _ptrFileUtilityObj = NULL; - } - - if(_ptrOutStream != NULL) - { - // If MediaFileImpl opened the OutStream it must be reclaimed here. - if(_openFile) - { - delete _ptrOutStream; - _openFile = false; - } - _ptrOutStream = NULL; - } - - _recordingActive = false; - codec_info_.pltype = 0; - codec_info_.plname[0] = '\0'; - - return 0; -} - -bool MediaFileImpl::IsRecording() -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsRecording()"); - CriticalSectionScoped lock(_crit); - return _recordingActive; -} - -int32_t MediaFileImpl::RecordDurationMs(uint32_t& durationMs) -{ - - CriticalSectionScoped lock(_crit); - if(!_recordingActive) - { - durationMs = 0; - return -1; - } - durationMs = _recordDurationMs; - return 0; -} - -bool MediaFileImpl::IsStereo() -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, "MediaFileImpl::IsStereo()"); - CriticalSectionScoped lock(_crit); - return _isStereo; -} - -int32_t MediaFileImpl::SetModuleFileCallback(FileCallback* callback) -{ - - CriticalSectionScoped lock(_callbackCrit); - - _ptrCallback = callback; - return 0; -} - -int32_t MediaFileImpl::FileDurationMs(const char* fileName, - uint32_t& durationMs, - const FileFormats format, - const uint32_t freqInHz) -{ - - if(!ValidFileName(fileName)) - { - return -1; - } - if(!ValidFrequency(freqInHz)) - { - return -1; - } - - ModuleFileUtility* utilityObj = new ModuleFileUtility(_id); - if(utilityObj == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "failed to allocate utility object!"); - return -1; - } - - const int32_t duration = utilityObj->FileDurationMs(fileName, format, - freqInHz); - delete utilityObj; - if(duration == -1) - { - durationMs = 0; - return -1; - } - - durationMs = duration; - return 0; -} - -int32_t MediaFileImpl::PlayoutPositionMs(uint32_t& positionMs) const -{ - CriticalSectionScoped lock(_crit); - if(!_playingActive) - { - positionMs = 0; - return -1; - } - positionMs = _playoutPositionMs; - return 0; -} - -int32_t MediaFileImpl::codec_info(CodecInst& codecInst) const -{ - CriticalSectionScoped lock(_crit); - if(!_playingActive && !_recordingActive) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Neither playout nor recording has been initialized!"); - return -1; - } - if (codec_info_.pltype == 0 && codec_info_.plname[0] == '\0') - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "The CodecInst for %s is unknown!", - _playingActive ? "Playback" : "Recording"); - return -1; - } - memcpy(&codecInst,&codec_info_,sizeof(CodecInst)); - return 0; -} - -bool MediaFileImpl::ValidFileFormat(const FileFormats format, - const CodecInst* codecInst) -{ - if(codecInst == NULL) - { - if(format == kFileFormatPreencodedFile || - format == kFileFormatPcm8kHzFile || - format == kFileFormatPcm16kHzFile || - format == kFileFormatPcm32kHzFile) - { - WEBRTC_TRACE(kTraceError, kTraceFile, -1, - "Codec info required for file format specified!"); - return false; - } - } - return true; -} - -bool MediaFileImpl::ValidFileName(const char* fileName) -{ - if((fileName == NULL) ||(fileName[0] == '\0')) - { - WEBRTC_TRACE(kTraceError, kTraceFile, -1, "FileName not specified!"); - return false; - } - return true; -} - - -bool MediaFileImpl::ValidFilePositions(const uint32_t startPointMs, - const uint32_t stopPointMs) -{ - if(startPointMs == 0 && stopPointMs == 0) // Default values - { - return true; - } - if(stopPointMs &&(startPointMs >= stopPointMs)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, -1, - "startPointMs must be less than stopPointMs!"); - return false; - } - if(stopPointMs &&((stopPointMs - startPointMs) < 20)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, -1, - "minimum play duration for files is 20 ms!"); - return false; - } - return true; -} - -bool MediaFileImpl::ValidFrequency(const uint32_t frequency) -{ - if((frequency == 8000) || (frequency == 16000)|| (frequency == 32000)) - { - return true; - } - WEBRTC_TRACE(kTraceError, kTraceFile, -1, - "Frequency should be 8000, 16000 or 32000 (Hz)"); - return false; -} -} // namespace webrtc diff --git a/webrtc/modules/media_file/source/media_file_impl.h b/webrtc/modules/media_file/source/media_file_impl.h deleted file mode 100644 index cdb54d880d..0000000000 --- a/webrtc/modules/media_file/source/media_file_impl.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_IMPL_H_ -#define WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_IMPL_H_ - -#include "webrtc/common_types.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/modules/media_file/interface/media_file.h" -#include "webrtc/modules/media_file/interface/media_file_defines.h" -#include "webrtc/modules/media_file/source/media_file_utility.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" - -namespace webrtc { -class MediaFileImpl : public MediaFile -{ - -public: - MediaFileImpl(const int32_t id); - ~MediaFileImpl(); - - int32_t Process() override; - int64_t TimeUntilNextProcess() override; - - // MediaFile functions - int32_t PlayoutAudioData(int8_t* audioBuffer, - size_t& dataLengthInBytes) override; - - int32_t PlayoutStereoData(int8_t* audioBufferLeft, - int8_t* audioBufferRight, - size_t& dataLengthInBytes) override; - - int32_t StartPlayingAudioFile( - const char* fileName, - const uint32_t notificationTimeMs = 0, - const bool loop = false, - const FileFormats format = kFileFormatPcm16kHzFile, - const CodecInst* codecInst = NULL, - const uint32_t startPointMs = 0, - const uint32_t stopPointMs = 0) override; - - int32_t StartPlayingAudioStream( - InStream& stream, - const uint32_t notificationTimeMs = 0, - const FileFormats format = kFileFormatPcm16kHzFile, - const CodecInst* codecInst = NULL, - const uint32_t startPointMs = 0, - const uint32_t stopPointMs = 0) override; - - int32_t StopPlaying() override; - - bool IsPlaying() override; - - int32_t PlayoutPositionMs(uint32_t& positionMs) const override; - - int32_t IncomingAudioData(const int8_t* audioBuffer, - const size_t bufferLength) override; - - int32_t StartRecordingAudioFile(const char* fileName, - const FileFormats format, - const CodecInst& codecInst, - const uint32_t notificationTimeMs = 0, - const uint32_t maxSizeBytes = 0) override; - - int32_t StartRecordingAudioStream( - OutStream& stream, - const FileFormats format, - const CodecInst& codecInst, - const uint32_t notificationTimeMs = 0) override; - - int32_t StopRecording() override; - - bool IsRecording() override; - - int32_t RecordDurationMs(uint32_t& durationMs) override; - - bool IsStereo() override; - - int32_t SetModuleFileCallback(FileCallback* callback) override; - - int32_t FileDurationMs(const char* fileName, - uint32_t& durationMs, - const FileFormats format, - const uint32_t freqInHz = 16000) override; - - int32_t codec_info(CodecInst& codecInst) const override; - -private: - // Returns true if the combination of format and codecInst is valid. - static bool ValidFileFormat(const FileFormats format, - const CodecInst* codecInst); - - - // Returns true if the filename is valid - static bool ValidFileName(const char* fileName); - - // Returns true if the combination of startPointMs and stopPointMs is valid. - static bool ValidFilePositions(const uint32_t startPointMs, - const uint32_t stopPointMs); - - // Returns true if frequencyInHz is a supported frequency. - static bool ValidFrequency(const uint32_t frequencyInHz); - - void HandlePlayCallbacks(int32_t bytesRead); - - int32_t StartPlayingStream( - InStream& stream, - bool loop, - const uint32_t notificationTimeMs, - const FileFormats format, - const CodecInst* codecInst, - const uint32_t startPointMs, - const uint32_t stopPointMs); - - int32_t _id; - CriticalSectionWrapper* _crit; - CriticalSectionWrapper* _callbackCrit; - - ModuleFileUtility* _ptrFileUtilityObj; - CodecInst codec_info_; - - InStream* _ptrInStream; - OutStream* _ptrOutStream; - - FileFormats _fileFormat; - uint32_t _recordDurationMs; - uint32_t _playoutPositionMs; - uint32_t _notificationMs; - - bool _playingActive; - bool _recordingActive; - bool _isStereo; - bool _openFile; - - char _fileName[512]; - - FileCallback* _ptrCallback; -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_IMPL_H_ diff --git a/webrtc/modules/media_file/source/media_file_unittest.cc b/webrtc/modules/media_file/source/media_file_unittest.cc deleted file mode 100644 index 370d13228a..0000000000 --- a/webrtc/modules/media_file/source/media_file_unittest.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/media_file/interface/media_file.h" -#include "webrtc/system_wrappers/include/sleep.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -class MediaFileTest : public testing::Test { - protected: - void SetUp() { - // Use number 0 as the the identifier and pass to CreateMediaFile. - media_file_ = webrtc::MediaFile::CreateMediaFile(0); - ASSERT_TRUE(media_file_ != NULL); - } - void TearDown() { - webrtc::MediaFile::DestroyMediaFile(media_file_); - media_file_ = NULL; - } - webrtc::MediaFile* media_file_; -}; - -TEST_F(MediaFileTest, DISABLED_ON_IOS( - DISABLED_ON_ANDROID(StartPlayingAudioFileWithoutError))) { - // TODO(leozwang): Use hard coded filename here, we want to - // loop through all audio files in future - const std::string audio_file = webrtc::test::ProjectRootPath() + - "data/voice_engine/audio_tiny48.wav"; - ASSERT_EQ(0, media_file_->StartPlayingAudioFile( - audio_file.c_str(), - 0, - false, - webrtc::kFileFormatWavFile)); - - ASSERT_EQ(true, media_file_->IsPlaying()); - - webrtc::SleepMs(1); - - ASSERT_EQ(0, media_file_->StopPlaying()); -} - -TEST_F(MediaFileTest, DISABLED_ON_IOS(WriteWavFile)) { - // Write file. - static const size_t kHeaderSize = 44; - static const size_t kPayloadSize = 320; - webrtc::CodecInst codec = { - 0, "L16", 16000, static_cast<int>(kPayloadSize), 1 - }; - std::string outfile = webrtc::test::OutputPath() + "wavtest.wav"; - ASSERT_EQ(0, - media_file_->StartRecordingAudioFile( - outfile.c_str(), webrtc::kFileFormatWavFile, codec)); - static const int8_t kFakeData[kPayloadSize] = {0}; - ASSERT_EQ(0, media_file_->IncomingAudioData(kFakeData, kPayloadSize)); - ASSERT_EQ(0, media_file_->StopRecording()); - - // Check the file we just wrote. - static const uint8_t kExpectedHeader[] = { - 'R', 'I', 'F', 'F', - 0x64, 0x1, 0, 0, // size of whole file - 8: 320 + 44 - 8 - 'W', 'A', 'V', 'E', - 'f', 'm', 't', ' ', - 0x10, 0, 0, 0, // size of fmt block - 8: 24 - 8 - 0x1, 0, // format: PCM (1) - 0x1, 0, // channels: 1 - 0x80, 0x3e, 0, 0, // sample rate: 16000 - 0, 0x7d, 0, 0, // byte rate: 2 * 16000 - 0x2, 0, // block align: NumChannels * BytesPerSample - 0x10, 0, // bits per sample: 2 * 8 - 'd', 'a', 't', 'a', - 0x40, 0x1, 0, 0, // size of payload: 320 - }; - static_assert(sizeof(kExpectedHeader) == kHeaderSize, "header size"); - - EXPECT_EQ(kHeaderSize + kPayloadSize, webrtc::test::GetFileSize(outfile)); - FILE* f = fopen(outfile.c_str(), "rb"); - ASSERT_TRUE(f); - - uint8_t header[kHeaderSize]; - ASSERT_EQ(1u, fread(header, kHeaderSize, 1, f)); - EXPECT_EQ(0, memcmp(kExpectedHeader, header, kHeaderSize)); - - uint8_t payload[kPayloadSize]; - ASSERT_EQ(1u, fread(payload, kPayloadSize, 1, f)); - EXPECT_EQ(0, memcmp(kFakeData, payload, kPayloadSize)); - - EXPECT_EQ(0, fclose(f)); -} diff --git a/webrtc/modules/media_file/source/media_file_utility.cc b/webrtc/modules/media_file/source/media_file_utility.cc deleted file mode 100644 index 61ae442d0e..0000000000 --- a/webrtc/modules/media_file/source/media_file_utility.cc +++ /dev/null @@ -1,1656 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/media_file/source/media_file_utility.h" - -#include <assert.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <limits> - -#include "webrtc/base/format_macros.h" -#include "webrtc/common_audio/wav_header.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/system_wrappers/include/file_wrapper.h" -#include "webrtc/system_wrappers/include/trace.h" - -namespace { - -// First 16 bytes the WAVE header. ckID should be "RIFF", wave_ckID should be -// "WAVE" and ckSize is the chunk size (4 + n) -struct WAVE_RIFF_header -{ - int8_t ckID[4]; - int32_t ckSize; - int8_t wave_ckID[4]; -}; - -// First 8 byte of the format chunk. fmt_ckID should be "fmt ". fmt_ckSize is -// the chunk size (16, 18 or 40 byte) -struct WAVE_CHUNK_header -{ - int8_t fmt_ckID[4]; - int32_t fmt_ckSize; -}; -} // unnamed namespace - -namespace webrtc { -ModuleFileUtility::ModuleFileUtility(const int32_t id) - : _wavFormatObj(), - _dataSize(0), - _readSizeBytes(0), - _id(id), - _stopPointInMs(0), - _startPointInMs(0), - _playoutPositionMs(0), - _bytesWritten(0), - codec_info_(), - _codecId(kCodecNoCodec), - _bytesPerSample(0), - _readPos(0), - _reading(false), - _writing(false), - _tempData() { - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, - "ModuleFileUtility::ModuleFileUtility()"); - memset(&codec_info_,0,sizeof(CodecInst)); - codec_info_.pltype = -1; -} - -ModuleFileUtility::~ModuleFileUtility() -{ - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, - "ModuleFileUtility::~ModuleFileUtility()"); -} - -int32_t ModuleFileUtility::ReadWavHeader(InStream& wav) -{ - WAVE_RIFF_header RIFFheaderObj; - WAVE_CHUNK_header CHUNKheaderObj; - // TODO (hellner): tmpStr and tmpStr2 seems unnecessary here. - char tmpStr[6] = "FOUR"; - unsigned char tmpStr2[4]; - int32_t i, len; - bool dataFound = false; - bool fmtFound = false; - int8_t dummyRead; - - - _dataSize = 0; - len = wav.Read(&RIFFheaderObj, sizeof(WAVE_RIFF_header)); - if(len != sizeof(WAVE_RIFF_header)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Not a wave file (too short)"); - return -1; - } - - for (i = 0; i < 4; i++) - { - tmpStr[i] = RIFFheaderObj.ckID[i]; - } - if(strcmp(tmpStr, "RIFF") != 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Not a wave file (does not have RIFF)"); - return -1; - } - for (i = 0; i < 4; i++) - { - tmpStr[i] = RIFFheaderObj.wave_ckID[i]; - } - if(strcmp(tmpStr, "WAVE") != 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Not a wave file (does not have WAVE)"); - return -1; - } - - len = wav.Read(&CHUNKheaderObj, sizeof(WAVE_CHUNK_header)); - - // WAVE files are stored in little endian byte order. Make sure that the - // data can be read on big endian as well. - // TODO (hellner): little endian to system byte order should be done in - // in a subroutine. - memcpy(tmpStr2, &CHUNKheaderObj.fmt_ckSize, 4); - CHUNKheaderObj.fmt_ckSize = - (int32_t) ((uint32_t) tmpStr2[0] + - (((uint32_t)tmpStr2[1])<<8) + - (((uint32_t)tmpStr2[2])<<16) + - (((uint32_t)tmpStr2[3])<<24)); - - memcpy(tmpStr, CHUNKheaderObj.fmt_ckID, 4); - - while ((len == sizeof(WAVE_CHUNK_header)) && (!fmtFound || !dataFound)) - { - if(strcmp(tmpStr, "fmt ") == 0) - { - len = wav.Read(&_wavFormatObj, sizeof(WAVE_FMTINFO_header)); - - memcpy(tmpStr2, &_wavFormatObj.formatTag, 2); - _wavFormatObj.formatTag = - (uint32_t)tmpStr2[0] + (((uint32_t)tmpStr2[1])<<8); - memcpy(tmpStr2, &_wavFormatObj.nChannels, 2); - _wavFormatObj.nChannels = - (int16_t) ((uint32_t)tmpStr2[0] + - (((uint32_t)tmpStr2[1])<<8)); - memcpy(tmpStr2, &_wavFormatObj.nSamplesPerSec, 4); - _wavFormatObj.nSamplesPerSec = - (int32_t) ((uint32_t)tmpStr2[0] + - (((uint32_t)tmpStr2[1])<<8) + - (((uint32_t)tmpStr2[2])<<16) + - (((uint32_t)tmpStr2[3])<<24)); - memcpy(tmpStr2, &_wavFormatObj.nAvgBytesPerSec, 4); - _wavFormatObj.nAvgBytesPerSec = - (int32_t) ((uint32_t)tmpStr2[0] + - (((uint32_t)tmpStr2[1])<<8) + - (((uint32_t)tmpStr2[2])<<16) + - (((uint32_t)tmpStr2[3])<<24)); - memcpy(tmpStr2, &_wavFormatObj.nBlockAlign, 2); - _wavFormatObj.nBlockAlign = - (int16_t) ((uint32_t)tmpStr2[0] + - (((uint32_t)tmpStr2[1])<<8)); - memcpy(tmpStr2, &_wavFormatObj.nBitsPerSample, 2); - _wavFormatObj.nBitsPerSample = - (int16_t) ((uint32_t)tmpStr2[0] + - (((uint32_t)tmpStr2[1])<<8)); - - for (i = 0; - i < (CHUNKheaderObj.fmt_ckSize - - (int32_t)sizeof(WAVE_FMTINFO_header)); - i++) - { - len = wav.Read(&dummyRead, 1); - if(len != 1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "File corrupted, reached EOF (reading fmt)"); - return -1; - } - } - fmtFound = true; - } - else if(strcmp(tmpStr, "data") == 0) - { - _dataSize = CHUNKheaderObj.fmt_ckSize; - dataFound = true; - break; - } - else - { - for (i = 0; i < (CHUNKheaderObj.fmt_ckSize); i++) - { - len = wav.Read(&dummyRead, 1); - if(len != 1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "File corrupted, reached EOF (reading other)"); - return -1; - } - } - } - - len = wav.Read(&CHUNKheaderObj, sizeof(WAVE_CHUNK_header)); - - memcpy(tmpStr2, &CHUNKheaderObj.fmt_ckSize, 4); - CHUNKheaderObj.fmt_ckSize = - (int32_t) ((uint32_t)tmpStr2[0] + - (((uint32_t)tmpStr2[1])<<8) + - (((uint32_t)tmpStr2[2])<<16) + - (((uint32_t)tmpStr2[3])<<24)); - - memcpy(tmpStr, CHUNKheaderObj.fmt_ckID, 4); - } - - // Either a proper format chunk has been read or a data chunk was come - // across. - if( (_wavFormatObj.formatTag != kWavFormatPcm) && - (_wavFormatObj.formatTag != kWavFormatALaw) && - (_wavFormatObj.formatTag != kWavFormatMuLaw)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Coding formatTag value=%d not supported!", - _wavFormatObj.formatTag); - return -1; - } - if((_wavFormatObj.nChannels < 1) || - (_wavFormatObj.nChannels > 2)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "nChannels value=%d not supported!", - _wavFormatObj.nChannels); - return -1; - } - - if((_wavFormatObj.nBitsPerSample != 8) && - (_wavFormatObj.nBitsPerSample != 16)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "nBitsPerSample value=%d not supported!", - _wavFormatObj.nBitsPerSample); - return -1; - } - - // Calculate the number of bytes that 10 ms of audio data correspond to. - if(_wavFormatObj.formatTag == kWavFormatPcm) - { - // TODO (hellner): integer division for 22050 and 11025 would yield - // the same result as the else statement. Remove those - // special cases? - if(_wavFormatObj.nSamplesPerSec == 44100) - { - _readSizeBytes = 440 * _wavFormatObj.nChannels * - (_wavFormatObj.nBitsPerSample / 8); - } else if(_wavFormatObj.nSamplesPerSec == 22050) { - _readSizeBytes = 220 * _wavFormatObj.nChannels * - (_wavFormatObj.nBitsPerSample / 8); - } else if(_wavFormatObj.nSamplesPerSec == 11025) { - _readSizeBytes = 110 * _wavFormatObj.nChannels * - (_wavFormatObj.nBitsPerSample / 8); - } else { - _readSizeBytes = (_wavFormatObj.nSamplesPerSec/100) * - _wavFormatObj.nChannels * (_wavFormatObj.nBitsPerSample / 8); - } - - } else { - _readSizeBytes = (_wavFormatObj.nSamplesPerSec/100) * - _wavFormatObj.nChannels * (_wavFormatObj.nBitsPerSample / 8); - } - return 0; -} - -int32_t ModuleFileUtility::InitWavCodec(uint32_t samplesPerSec, - uint32_t channels, - uint32_t bitsPerSample, - uint32_t formatTag) -{ - codec_info_.pltype = -1; - codec_info_.plfreq = samplesPerSec; - codec_info_.channels = channels; - codec_info_.rate = bitsPerSample * samplesPerSec; - - // Calculate the packet size for 10ms frames - switch(formatTag) - { - case kWavFormatALaw: - strcpy(codec_info_.plname, "PCMA"); - _codecId = kCodecPcma; - codec_info_.pltype = 8; - codec_info_.pacsize = codec_info_.plfreq / 100; - break; - case kWavFormatMuLaw: - strcpy(codec_info_.plname, "PCMU"); - _codecId = kCodecPcmu; - codec_info_.pltype = 0; - codec_info_.pacsize = codec_info_.plfreq / 100; - break; - case kWavFormatPcm: - codec_info_.pacsize = (bitsPerSample * (codec_info_.plfreq / 100)) / 8; - if(samplesPerSec == 8000) - { - strcpy(codec_info_.plname, "L16"); - _codecId = kCodecL16_8Khz; - } - else if(samplesPerSec == 16000) - { - strcpy(codec_info_.plname, "L16"); - _codecId = kCodecL16_16kHz; - } - else if(samplesPerSec == 32000) - { - strcpy(codec_info_.plname, "L16"); - _codecId = kCodecL16_32Khz; - } - // Set the packet size for "odd" sampling frequencies so that it - // properly corresponds to _readSizeBytes. - else if(samplesPerSec == 11025) - { - strcpy(codec_info_.plname, "L16"); - _codecId = kCodecL16_16kHz; - codec_info_.pacsize = 110; - codec_info_.plfreq = 11000; - } - else if(samplesPerSec == 22050) - { - strcpy(codec_info_.plname, "L16"); - _codecId = kCodecL16_16kHz; - codec_info_.pacsize = 220; - codec_info_.plfreq = 22000; - } - else if(samplesPerSec == 44100) - { - strcpy(codec_info_.plname, "L16"); - _codecId = kCodecL16_16kHz; - codec_info_.pacsize = 440; - codec_info_.plfreq = 44000; - } - else if(samplesPerSec == 48000) - { - strcpy(codec_info_.plname, "L16"); - _codecId = kCodecL16_16kHz; - codec_info_.pacsize = 480; - codec_info_.plfreq = 48000; - } - else - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Unsupported PCM frequency!"); - return -1; - } - break; - default: - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "unknown WAV format TAG!"); - return -1; - break; - } - return 0; -} - -int32_t ModuleFileUtility::InitWavReading(InStream& wav, - const uint32_t start, - const uint32_t stop) -{ - - _reading = false; - - if(ReadWavHeader(wav) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "failed to read WAV header!"); - return -1; - } - - _playoutPositionMs = 0; - _readPos = 0; - - if(start > 0) - { - uint8_t dummy[WAV_MAX_BUFFER_SIZE]; - int32_t readLength; - if(_readSizeBytes <= WAV_MAX_BUFFER_SIZE) - { - while (_playoutPositionMs < start) - { - readLength = wav.Read(dummy, _readSizeBytes); - if(readLength == _readSizeBytes) - { - _readPos += readLength; - _playoutPositionMs += 10; - } - else // Must have reached EOF before start position! - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "InitWavReading(), EOF before start position"); - return -1; - } - } - } - else - { - return -1; - } - } - if( InitWavCodec(_wavFormatObj.nSamplesPerSec, _wavFormatObj.nChannels, - _wavFormatObj.nBitsPerSample, - _wavFormatObj.formatTag) != 0) - { - return -1; - } - _bytesPerSample = _wavFormatObj.nBitsPerSample / 8; - - - _startPointInMs = start; - _stopPointInMs = stop; - _reading = true; - return 0; -} - -int32_t ModuleFileUtility::ReadWavDataAsMono( - InStream& wav, - int8_t* outData, - const size_t bufferSize) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::ReadWavDataAsMono(wav= 0x%x, outData= 0x%d, " - "bufSize= %" PRIuS ")", - &wav, - outData, - bufferSize); - - // The number of bytes that should be read from file. - const uint32_t totalBytesNeeded = _readSizeBytes; - // The number of bytes that will be written to outData. - const uint32_t bytesRequested = (codec_info_.channels == 2) ? - totalBytesNeeded >> 1 : totalBytesNeeded; - if(bufferSize < bytesRequested) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsMono: output buffer is too short!"); - return -1; - } - if(outData == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsMono: output buffer NULL!"); - return -1; - } - - if(!_reading) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsMono: no longer reading file."); - return -1; - } - - int32_t bytesRead = ReadWavData( - wav, - (codec_info_.channels == 2) ? _tempData : (uint8_t*)outData, - totalBytesNeeded); - if(bytesRead == 0) - { - return 0; - } - if(bytesRead < 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsMono: failed to read data from WAV file."); - return -1; - } - // Output data is should be mono. - if(codec_info_.channels == 2) - { - for (uint32_t i = 0; i < bytesRequested / _bytesPerSample; i++) - { - // Sample value is the average of left and right buffer rounded to - // closest integer value. Note samples can be either 1 or 2 byte. - if(_bytesPerSample == 1) - { - _tempData[i] = ((_tempData[2 * i] + _tempData[(2 * i) + 1] + - 1) >> 1); - } - else - { - int16_t* sampleData = (int16_t*) _tempData; - sampleData[i] = ((sampleData[2 * i] + sampleData[(2 * i) + 1] + - 1) >> 1); - } - } - memcpy(outData, _tempData, bytesRequested); - } - return bytesRequested; -} - -int32_t ModuleFileUtility::ReadWavDataAsStereo( - InStream& wav, - int8_t* outDataLeft, - int8_t* outDataRight, - const size_t bufferSize) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::ReadWavDataAsStereo(wav= 0x%x, outLeft= 0x%x, " - "outRight= 0x%x, bufSize= %" PRIuS ")", - &wav, - outDataLeft, - outDataRight, - bufferSize); - - if((outDataLeft == NULL) || - (outDataRight == NULL)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsMono: an input buffer is NULL!"); - return -1; - } - if(codec_info_.channels != 2) - { - WEBRTC_TRACE( - kTraceError, - kTraceFile, - _id, - "ReadWavDataAsStereo: WAV file does not contain stereo data!"); - return -1; - } - if(! _reading) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsStereo: no longer reading file."); - return -1; - } - - // The number of bytes that should be read from file. - const uint32_t totalBytesNeeded = _readSizeBytes; - // The number of bytes that will be written to the left and the right - // buffers. - const uint32_t bytesRequested = totalBytesNeeded >> 1; - if(bufferSize < bytesRequested) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavData: Output buffers are too short!"); - assert(false); - return -1; - } - - int32_t bytesRead = ReadWavData(wav, _tempData, totalBytesNeeded); - if(bytesRead <= 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsStereo: failed to read data from WAV file."); - return -1; - } - - // Turn interleaved audio to left and right buffer. Note samples can be - // either 1 or 2 bytes - if(_bytesPerSample == 1) - { - for (uint32_t i = 0; i < bytesRequested; i++) - { - outDataLeft[i] = _tempData[2 * i]; - outDataRight[i] = _tempData[(2 * i) + 1]; - } - } - else if(_bytesPerSample == 2) - { - int16_t* sampleData = reinterpret_cast<int16_t*>(_tempData); - int16_t* outLeft = reinterpret_cast<int16_t*>(outDataLeft); - int16_t* outRight = reinterpret_cast<int16_t*>( - outDataRight); - - // Bytes requested to samples requested. - uint32_t sampleCount = bytesRequested >> 1; - for (uint32_t i = 0; i < sampleCount; i++) - { - outLeft[i] = sampleData[2 * i]; - outRight[i] = sampleData[(2 * i) + 1]; - } - } else { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavStereoData: unsupported sample size %d!", - _bytesPerSample); - assert(false); - return -1; - } - return bytesRequested; -} - -int32_t ModuleFileUtility::ReadWavData( - InStream& wav, - uint8_t* buffer, - const uint32_t dataLengthInBytes) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::ReadWavData(wav= 0x%x, buffer= 0x%x, dataLen= %ld)", - &wav, - buffer, - dataLengthInBytes); - - - if(buffer == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadWavDataAsMono: output buffer NULL!"); - return -1; - } - - // Make sure that a read won't return too few samples. - // TODO (hellner): why not read the remaining bytes needed from the start - // of the file? - if((_dataSize - _readPos) < (int32_t)dataLengthInBytes) - { - // Rewind() being -1 may be due to the file not supposed to be looped. - if(wav.Rewind() == -1) - { - _reading = false; - return 0; - } - if(InitWavReading(wav, _startPointInMs, _stopPointInMs) == -1) - { - _reading = false; - return -1; - } - } - - int32_t bytesRead = wav.Read(buffer, dataLengthInBytes); - if(bytesRead < 0) - { - _reading = false; - return -1; - } - - // This should never happen due to earlier sanity checks. - // TODO (hellner): change to an assert and fail here since this should - // never happen... - if(bytesRead < (int32_t)dataLengthInBytes) - { - if((wav.Rewind() == -1) || - (InitWavReading(wav, _startPointInMs, _stopPointInMs) == -1)) - { - _reading = false; - return -1; - } - else - { - bytesRead = wav.Read(buffer, dataLengthInBytes); - if(bytesRead < (int32_t)dataLengthInBytes) - { - _reading = false; - return -1; - } - } - } - - _readPos += bytesRead; - - // TODO (hellner): Why is dataLengthInBytes let dictate the number of bytes - // to read when exactly 10ms should be read?! - _playoutPositionMs += 10; - if((_stopPointInMs > 0) && - (_playoutPositionMs >= _stopPointInMs)) - { - if((wav.Rewind() == -1) || - (InitWavReading(wav, _startPointInMs, _stopPointInMs) == -1)) - { - _reading = false; - } - } - return bytesRead; -} - -int32_t ModuleFileUtility::InitWavWriting(OutStream& wav, - const CodecInst& codecInst) -{ - - if(set_codec_info(codecInst) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "codecInst identifies unsupported codec!"); - return -1; - } - _writing = false; - uint32_t channels = (codecInst.channels == 0) ? - 1 : codecInst.channels; - - if(STR_CASE_CMP(codecInst.plname, "PCMU") == 0) - { - _bytesPerSample = 1; - if(WriteWavHeader(wav, 8000, _bytesPerSample, channels, - kWavFormatMuLaw, 0) == -1) - { - return -1; - } - }else if(STR_CASE_CMP(codecInst.plname, "PCMA") == 0) - { - _bytesPerSample = 1; - if(WriteWavHeader(wav, 8000, _bytesPerSample, channels, kWavFormatALaw, - 0) == -1) - { - return -1; - } - } - else if(STR_CASE_CMP(codecInst.plname, "L16") == 0) - { - _bytesPerSample = 2; - if(WriteWavHeader(wav, codecInst.plfreq, _bytesPerSample, channels, - kWavFormatPcm, 0) == -1) - { - return -1; - } - } - else - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "codecInst identifies unsupported codec for WAV file!"); - return -1; - } - _writing = true; - _bytesWritten = 0; - return 0; -} - -int32_t ModuleFileUtility::WriteWavData(OutStream& out, - const int8_t* buffer, - const size_t dataLength) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::WriteWavData(out= 0x%x, buf= 0x%x, dataLen= %" PRIuS - ")", - &out, - buffer, - dataLength); - - if(buffer == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "WriteWavData: input buffer NULL!"); - return -1; - } - - if(!out.Write(buffer, dataLength)) - { - return -1; - } - _bytesWritten += dataLength; - return static_cast<int32_t>(dataLength); -} - - -int32_t ModuleFileUtility::WriteWavHeader( - OutStream& wav, - const uint32_t freq, - const uint32_t bytesPerSample, - const uint32_t channels, - const uint32_t format, - const uint32_t lengthInBytes) -{ - // Frame size in bytes for 10 ms of audio. - // TODO (hellner): 44.1 kHz has 440 samples frame size. Doesn't seem to - // be taken into consideration here! - const int32_t frameSize = (freq / 100) * channels; - - // Calculate the number of full frames that the wave file contain. - const int32_t dataLengthInBytes = frameSize * (lengthInBytes / frameSize); - - uint8_t buf[kWavHeaderSize]; - webrtc::WriteWavHeader(buf, channels, freq, static_cast<WavFormat>(format), - bytesPerSample, dataLengthInBytes / bytesPerSample); - wav.Write(buf, kWavHeaderSize); - return 0; -} - -int32_t ModuleFileUtility::UpdateWavHeader(OutStream& wav) -{ - int32_t res = -1; - if(wav.Rewind() == -1) - { - return -1; - } - uint32_t channels = (codec_info_.channels == 0) ? - 1 : codec_info_.channels; - - if(STR_CASE_CMP(codec_info_.plname, "L16") == 0) - { - res = WriteWavHeader(wav, codec_info_.plfreq, 2, channels, - kWavFormatPcm, _bytesWritten); - } else if(STR_CASE_CMP(codec_info_.plname, "PCMU") == 0) { - res = WriteWavHeader(wav, 8000, 1, channels, kWavFormatMuLaw, - _bytesWritten); - } else if(STR_CASE_CMP(codec_info_.plname, "PCMA") == 0) { - res = WriteWavHeader(wav, 8000, 1, channels, kWavFormatALaw, - _bytesWritten); - } else { - // Allow calling this API even if not writing to a WAVE file. - // TODO (hellner): why?! - return 0; - } - return res; -} - - -int32_t ModuleFileUtility::InitPreEncodedReading(InStream& in, - const CodecInst& cinst) -{ - - uint8_t preEncodedID; - in.Read(&preEncodedID, 1); - - MediaFileUtility_CodecType codecType = - (MediaFileUtility_CodecType)preEncodedID; - - if(set_codec_info(cinst) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Pre-encoded file send codec mismatch!"); - return -1; - } - if(codecType != _codecId) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "Pre-encoded file format codec mismatch!"); - return -1; - } - memcpy(&codec_info_,&cinst,sizeof(CodecInst)); - _reading = true; - return 0; -} - -int32_t ModuleFileUtility::ReadPreEncodedData( - InStream& in, - int8_t* outData, - const size_t bufferSize) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::ReadPreEncodedData(in= 0x%x, outData= 0x%x, " - "bufferSize= %" PRIuS ")", - &in, - outData, - bufferSize); - - if(outData == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, "output buffer NULL"); - } - - uint32_t frameLen; - uint8_t buf[64]; - // Each frame has a two byte header containing the frame length. - int32_t res = in.Read(buf, 2); - if(res != 2) - { - if(!in.Rewind()) - { - // The first byte is the codec identifier. - in.Read(buf, 1); - res = in.Read(buf, 2); - } - else - { - return -1; - } - } - frameLen = buf[0] + buf[1] * 256; - if(bufferSize < frameLen) - { - WEBRTC_TRACE( - kTraceError, - kTraceFile, - _id, - "buffer not large enough to read %d bytes of pre-encoded data!", - frameLen); - return -1; - } - return in.Read(outData, frameLen); -} - -int32_t ModuleFileUtility::InitPreEncodedWriting( - OutStream& out, - const CodecInst& codecInst) -{ - - if(set_codec_info(codecInst) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, "CodecInst not recognized!"); - return -1; - } - _writing = true; - _bytesWritten = 1; - out.Write(&_codecId, 1); - return 0; -} - -int32_t ModuleFileUtility::WritePreEncodedData( - OutStream& out, - const int8_t* buffer, - const size_t dataLength) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::WritePreEncodedData(out= 0x%x, inData= 0x%x, " - "dataLen= %" PRIuS ")", - &out, - buffer, - dataLength); - - if(buffer == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id,"buffer NULL"); - } - - size_t bytesWritten = 0; - // The first two bytes is the size of the frame. - int16_t lengthBuf; - lengthBuf = (int16_t)dataLength; - if(dataLength > static_cast<size_t>(std::numeric_limits<int16_t>::max()) || - !out.Write(&lengthBuf, 2)) - { - return -1; - } - bytesWritten = 2; - - if(!out.Write(buffer, dataLength)) - { - return -1; - } - bytesWritten += dataLength; - return static_cast<int32_t>(bytesWritten); -} - -int32_t ModuleFileUtility::InitCompressedReading( - InStream& in, - const uint32_t start, - const uint32_t stop) -{ - WEBRTC_TRACE( - kTraceDebug, - kTraceFile, - _id, - "ModuleFileUtility::InitCompressedReading(in= 0x%x, start= %d,\ - stop= %d)", - &in, - start, - stop); - -#if defined(WEBRTC_CODEC_ILBC) - int16_t read_len = 0; -#endif - _codecId = kCodecNoCodec; - _playoutPositionMs = 0; - _reading = false; - - _startPointInMs = start; - _stopPointInMs = stop; - - // Read the codec name - int32_t cnt = 0; - char buf[64]; - do - { - in.Read(&buf[cnt++], 1); - } while ((buf[cnt-1] != '\n') && (64 > cnt)); - - if(cnt==64) - { - return -1; - } else { - buf[cnt]=0; - } - -#ifdef WEBRTC_CODEC_ILBC - if(!strcmp("#!iLBC20\n", buf)) - { - codec_info_.pltype = 102; - strcpy(codec_info_.plname, "ilbc"); - codec_info_.plfreq = 8000; - codec_info_.pacsize = 160; - codec_info_.channels = 1; - codec_info_.rate = 13300; - _codecId = kCodecIlbc20Ms; - - if(_startPointInMs > 0) - { - while (_playoutPositionMs <= _startPointInMs) - { - read_len = in.Read(buf, 38); - if(read_len == 38) - { - _playoutPositionMs += 20; - } - else - { - return -1; - } - } - } - } - - if(!strcmp("#!iLBC30\n", buf)) - { - codec_info_.pltype = 102; - strcpy(codec_info_.plname, "ilbc"); - codec_info_.plfreq = 8000; - codec_info_.pacsize = 240; - codec_info_.channels = 1; - codec_info_.rate = 13300; - _codecId = kCodecIlbc30Ms; - - if(_startPointInMs > 0) - { - while (_playoutPositionMs <= _startPointInMs) - { - read_len = in.Read(buf, 50); - if(read_len == 50) - { - _playoutPositionMs += 20; - } - else - { - return -1; - } - } - } - } -#endif - if(_codecId == kCodecNoCodec) - { - return -1; - } - _reading = true; - return 0; -} - -int32_t ModuleFileUtility::ReadCompressedData(InStream& in, - int8_t* outData, - size_t bufferSize) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::ReadCompressedData(in=0x%x, outData=0x%x, bytes=%" - PRIuS ")", - &in, - outData, - bufferSize); - - uint32_t bytesRead = 0; - - if(! _reading) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, "not currently reading!"); - return -1; - } - -#ifdef WEBRTC_CODEC_ILBC - if((_codecId == kCodecIlbc20Ms) || - (_codecId == kCodecIlbc30Ms)) - { - uint32_t byteSize = 0; - if(_codecId == kCodecIlbc30Ms) - { - byteSize = 50; - } - if(_codecId == kCodecIlbc20Ms) - { - byteSize = 38; - } - if(bufferSize < byteSize) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "output buffer is too short to read ILBC compressed\ - data."); - assert(false); - return -1; - } - - bytesRead = in.Read(outData, byteSize); - if(bytesRead != byteSize) - { - if(!in.Rewind()) - { - InitCompressedReading(in, _startPointInMs, _stopPointInMs); - bytesRead = in.Read(outData, byteSize); - if(bytesRead != byteSize) - { - _reading = false; - return -1; - } - } - else - { - _reading = false; - return -1; - } - } - } -#endif - if(bytesRead == 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadCompressedData() no bytes read, codec not supported"); - return -1; - } - - _playoutPositionMs += 20; - if((_stopPointInMs > 0) && - (_playoutPositionMs >= _stopPointInMs)) - { - if(!in.Rewind()) - { - InitCompressedReading(in, _startPointInMs, _stopPointInMs); - } - else - { - _reading = false; - } - } - return bytesRead; -} - -int32_t ModuleFileUtility::InitCompressedWriting( - OutStream& out, - const CodecInst& codecInst) -{ - WEBRTC_TRACE(kTraceDebug, kTraceFile, _id, - "ModuleFileUtility::InitCompressedWriting(out= 0x%x,\ - codecName= %s)", - &out, codecInst.plname); - - _writing = false; - -#ifdef WEBRTC_CODEC_ILBC - if(STR_CASE_CMP(codecInst.plname, "ilbc") == 0) - { - if(codecInst.pacsize == 160) - { - _codecId = kCodecIlbc20Ms; - out.Write("#!iLBC20\n",9); - } - else if(codecInst.pacsize == 240) - { - _codecId = kCodecIlbc30Ms; - out.Write("#!iLBC30\n",9); - } - else - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "codecInst defines unsupported compression codec!"); - return -1; - } - memcpy(&codec_info_,&codecInst,sizeof(CodecInst)); - _writing = true; - return 0; - } -#endif - - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "codecInst defines unsupported compression codec!"); - return -1; -} - -int32_t ModuleFileUtility::WriteCompressedData( - OutStream& out, - const int8_t* buffer, - const size_t dataLength) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::WriteCompressedData(out= 0x%x, buf= 0x%x, " - "dataLen= %" PRIuS ")", - &out, - buffer, - dataLength); - - if(buffer == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id,"buffer NULL"); - } - - if(!out.Write(buffer, dataLength)) - { - return -1; - } - return static_cast<int32_t>(dataLength); -} - -int32_t ModuleFileUtility::InitPCMReading(InStream& pcm, - const uint32_t start, - const uint32_t stop, - uint32_t freq) -{ - WEBRTC_TRACE( - kTraceInfo, - kTraceFile, - _id, - "ModuleFileUtility::InitPCMReading(pcm= 0x%x, start=%d, stop=%d,\ - freq=%d)", - &pcm, - start, - stop, - freq); - - int8_t dummy[320]; - int32_t read_len; - - _playoutPositionMs = 0; - _startPointInMs = start; - _stopPointInMs = stop; - _reading = false; - - if(freq == 8000) - { - strcpy(codec_info_.plname, "L16"); - codec_info_.pltype = -1; - codec_info_.plfreq = 8000; - codec_info_.pacsize = 160; - codec_info_.channels = 1; - codec_info_.rate = 128000; - _codecId = kCodecL16_8Khz; - } - else if(freq == 16000) - { - strcpy(codec_info_.plname, "L16"); - codec_info_.pltype = -1; - codec_info_.plfreq = 16000; - codec_info_.pacsize = 320; - codec_info_.channels = 1; - codec_info_.rate = 256000; - _codecId = kCodecL16_16kHz; - } - else if(freq == 32000) - { - strcpy(codec_info_.plname, "L16"); - codec_info_.pltype = -1; - codec_info_.plfreq = 32000; - codec_info_.pacsize = 320; - codec_info_.channels = 1; - codec_info_.rate = 512000; - _codecId = kCodecL16_32Khz; - } - - // Readsize for 10ms of audio data (2 bytes per sample). - _readSizeBytes = 2 * codec_info_. plfreq / 100; - if(_startPointInMs > 0) - { - while (_playoutPositionMs < _startPointInMs) - { - read_len = pcm.Read(dummy, _readSizeBytes); - if(read_len == _readSizeBytes) - { - _playoutPositionMs += 10; - } - else // Must have reached EOF before start position! - { - return -1; - } - } - } - _reading = true; - return 0; -} - -int32_t ModuleFileUtility::ReadPCMData(InStream& pcm, - int8_t* outData, - size_t bufferSize) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::ReadPCMData(pcm= 0x%x, outData= 0x%x, bufSize= %" - PRIuS ")", - &pcm, - outData, - bufferSize); - - if(outData == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id,"buffer NULL"); - } - - // Readsize for 10ms of audio data (2 bytes per sample). - uint32_t bytesRequested = 2 * codec_info_.plfreq / 100; - if(bufferSize < bytesRequested) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadPCMData: buffer not long enough for a 10ms frame."); - assert(false); - return -1; - } - - uint32_t bytesRead = pcm.Read(outData, bytesRequested); - if(bytesRead < bytesRequested) - { - if(pcm.Rewind() == -1) - { - _reading = false; - } - else - { - if(InitPCMReading(pcm, _startPointInMs, _stopPointInMs, - codec_info_.plfreq) == -1) - { - _reading = false; - } - else - { - int32_t rest = bytesRequested - bytesRead; - int32_t len = pcm.Read(&(outData[bytesRead]), rest); - if(len == rest) - { - bytesRead += len; - } - else - { - _reading = false; - } - } - if(bytesRead <= 0) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "ReadPCMData: Failed to rewind audio file."); - return -1; - } - } - } - - if(bytesRead <= 0) - { - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, - "ReadPCMData: end of file"); - return -1; - } - _playoutPositionMs += 10; - if(_stopPointInMs && _playoutPositionMs >= _stopPointInMs) - { - if(!pcm.Rewind()) - { - if(InitPCMReading(pcm, _startPointInMs, _stopPointInMs, - codec_info_.plfreq) == -1) - { - _reading = false; - } - } - } - return bytesRead; -} - -int32_t ModuleFileUtility::InitPCMWriting(OutStream& out, uint32_t freq) -{ - - if(freq == 8000) - { - strcpy(codec_info_.plname, "L16"); - codec_info_.pltype = -1; - codec_info_.plfreq = 8000; - codec_info_.pacsize = 160; - codec_info_.channels = 1; - codec_info_.rate = 128000; - - _codecId = kCodecL16_8Khz; - } - else if(freq == 16000) - { - strcpy(codec_info_.plname, "L16"); - codec_info_.pltype = -1; - codec_info_.plfreq = 16000; - codec_info_.pacsize = 320; - codec_info_.channels = 1; - codec_info_.rate = 256000; - - _codecId = kCodecL16_16kHz; - } - else if(freq == 32000) - { - strcpy(codec_info_.plname, "L16"); - codec_info_.pltype = -1; - codec_info_.plfreq = 32000; - codec_info_.pacsize = 320; - codec_info_.channels = 1; - codec_info_.rate = 512000; - - _codecId = kCodecL16_32Khz; - } - if((_codecId != kCodecL16_8Khz) && - (_codecId != kCodecL16_16kHz) && - (_codecId != kCodecL16_32Khz)) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "CodecInst is not 8KHz PCM or 16KHz PCM!"); - return -1; - } - _writing = true; - _bytesWritten = 0; - return 0; -} - -int32_t ModuleFileUtility::WritePCMData(OutStream& out, - const int8_t* buffer, - const size_t dataLength) -{ - WEBRTC_TRACE( - kTraceStream, - kTraceFile, - _id, - "ModuleFileUtility::WritePCMData(out= 0x%x, buf= 0x%x, dataLen= %" PRIuS - ")", - &out, - buffer, - dataLength); - - if(buffer == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, "buffer NULL"); - } - - if(!out.Write(buffer, dataLength)) - { - return -1; - } - - _bytesWritten += dataLength; - return static_cast<int32_t>(dataLength); -} - -int32_t ModuleFileUtility::codec_info(CodecInst& codecInst) -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, - "ModuleFileUtility::codec_info(codecInst= 0x%x)", &codecInst); - - if(!_reading && !_writing) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "CodecInst: not currently reading audio file!"); - return -1; - } - memcpy(&codecInst,&codec_info_,sizeof(CodecInst)); - return 0; -} - -int32_t ModuleFileUtility::set_codec_info(const CodecInst& codecInst) -{ - - _codecId = kCodecNoCodec; - if(STR_CASE_CMP(codecInst.plname, "PCMU") == 0) - { - _codecId = kCodecPcmu; - } - else if(STR_CASE_CMP(codecInst.plname, "PCMA") == 0) - { - _codecId = kCodecPcma; - } - else if(STR_CASE_CMP(codecInst.plname, "L16") == 0) - { - if(codecInst.plfreq == 8000) - { - _codecId = kCodecL16_8Khz; - } - else if(codecInst.plfreq == 16000) - { - _codecId = kCodecL16_16kHz; - } - else if(codecInst.plfreq == 32000) - { - _codecId = kCodecL16_32Khz; - } - } -#ifdef WEBRTC_CODEC_ILBC - else if(STR_CASE_CMP(codecInst.plname, "ilbc") == 0) - { - if(codecInst.pacsize == 160) - { - _codecId = kCodecIlbc20Ms; - } - else if(codecInst.pacsize == 240) - { - _codecId = kCodecIlbc30Ms; - } - } -#endif -#if(defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) - else if(STR_CASE_CMP(codecInst.plname, "isac") == 0) - { - if(codecInst.plfreq == 16000) - { - _codecId = kCodecIsac; - } - else if(codecInst.plfreq == 32000) - { - _codecId = kCodecIsacSwb; - } - } -#endif -#ifdef WEBRTC_CODEC_G722 - else if(STR_CASE_CMP(codecInst.plname, "G722") == 0) - { - _codecId = kCodecG722; - } -#endif - if(_codecId == kCodecNoCodec) - { - return -1; - } - memcpy(&codec_info_, &codecInst, sizeof(CodecInst)); - return 0; -} - -int32_t ModuleFileUtility::FileDurationMs(const char* fileName, - const FileFormats fileFormat, - const uint32_t freqInHz) -{ - - if(fileName == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, "filename NULL"); - return -1; - } - - int32_t time_in_ms = -1; - struct stat file_size; - if(stat(fileName,&file_size) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "failed to retrieve file size with stat!"); - return -1; - } - FileWrapper* inStreamObj = FileWrapper::Create(); - if(inStreamObj == NULL) - { - WEBRTC_TRACE(kTraceMemory, kTraceFile, _id, - "failed to create InStream object!"); - return -1; - } - if(inStreamObj->OpenFile(fileName, true) == -1) - { - delete inStreamObj; - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "failed to open file %s!", fileName); - return -1; - } - - switch (fileFormat) - { - case kFileFormatWavFile: - { - if(ReadWavHeader(*inStreamObj) == -1) - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "failed to read WAV file header!"); - return -1; - } - time_in_ms = ((file_size.st_size - 44) / - (_wavFormatObj.nAvgBytesPerSec/1000)); - break; - } - case kFileFormatPcm16kHzFile: - { - // 16 samples per ms. 2 bytes per sample. - int32_t denominator = 16*2; - time_in_ms = (file_size.st_size)/denominator; - break; - } - case kFileFormatPcm8kHzFile: - { - // 8 samples per ms. 2 bytes per sample. - int32_t denominator = 8*2; - time_in_ms = (file_size.st_size)/denominator; - break; - } - case kFileFormatCompressedFile: - { - int32_t cnt = 0; - int32_t read_len = 0; - char buf[64]; - do - { - read_len = inStreamObj->Read(&buf[cnt++], 1); - if(read_len != 1) - { - return -1; - } - } while ((buf[cnt-1] != '\n') && (64 > cnt)); - - if(cnt == 64) - { - return -1; - } - else - { - buf[cnt] = 0; - } -#ifdef WEBRTC_CODEC_ILBC - if(!strcmp("#!iLBC20\n", buf)) - { - // 20 ms is 304 bits - time_in_ms = ((file_size.st_size)*160)/304; - break; - } - if(!strcmp("#!iLBC30\n", buf)) - { - // 30 ms takes 400 bits. - // file size in bytes * 8 / 400 is the number of - // 30 ms frames in the file -> - // time_in_ms = file size * 8 / 400 * 30 - time_in_ms = ((file_size.st_size)*240)/400; - break; - } -#endif - break; - } - case kFileFormatPreencodedFile: - { - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "cannot determine duration of Pre-Encoded file!"); - break; - } - default: - WEBRTC_TRACE(kTraceError, kTraceFile, _id, - "unsupported file format %d!", fileFormat); - break; - } - inStreamObj->CloseFile(); - delete inStreamObj; - return time_in_ms; -} - -uint32_t ModuleFileUtility::PlayoutPositionMs() -{ - WEBRTC_TRACE(kTraceStream, kTraceFile, _id, - "ModuleFileUtility::PlayoutPosition()"); - - if(_reading) - { - return _playoutPositionMs; - } - else - { - return 0; - } -} -} // namespace webrtc diff --git a/webrtc/modules/media_file/source/media_file_utility.h b/webrtc/modules/media_file/source/media_file_utility.h deleted file mode 100644 index 2823ceca8a..0000000000 --- a/webrtc/modules/media_file/source/media_file_utility.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// Note: the class cannot be used for reading and writing at the same time. -#ifndef WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_UTILITY_H_ -#define WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_UTILITY_H_ - -#include <stdio.h> - -#include "webrtc/common_types.h" -#include "webrtc/modules/media_file/interface/media_file_defines.h" - -namespace webrtc { -class InStream; -class OutStream; - -class ModuleFileUtility -{ -public: - - ModuleFileUtility(const int32_t id); - ~ModuleFileUtility(); - - // Prepare for playing audio from stream. - // startPointMs and stopPointMs, unless zero, specify what part of the file - // should be read. From startPointMs ms to stopPointMs ms. - int32_t InitWavReading(InStream& stream, - const uint32_t startPointMs = 0, - const uint32_t stopPointMs = 0); - - // Put 10-60ms of audio data from stream into the audioBuffer depending on - // codec frame size. dataLengthInBytes indicates the size of audioBuffer. - // The return value is the number of bytes written to audioBuffer. - // Note: This API only play mono audio but can be used on file containing - // audio with more channels (in which case the audio will be converted to - // mono). - int32_t ReadWavDataAsMono(InStream& stream, int8_t* audioBuffer, - const size_t dataLengthInBytes); - - // Put 10-60ms, depending on codec frame size, of audio data from file into - // audioBufferLeft and audioBufferRight. The buffers contain the left and - // right channel of played out stereo audio. - // dataLengthInBytes indicates the size of both audioBufferLeft and - // audioBufferRight. - // The return value is the number of bytes read for each buffer. - // Note: This API can only be successfully called for WAV files with stereo - // audio. - int32_t ReadWavDataAsStereo(InStream& wav, - int8_t* audioBufferLeft, - int8_t* audioBufferRight, - const size_t bufferLength); - - // Prepare for recording audio to stream. - // codecInst specifies the encoding of the audio data. - // Note: codecInst.channels should be set to 2 for stereo (and 1 for - // mono). Stereo is only supported for WAV files. - int32_t InitWavWriting(OutStream& stream, const CodecInst& codecInst); - - // Write one audio frame, i.e. the bufferLength first bytes of audioBuffer, - // to file. The audio frame size is determined by the codecInst.pacsize - // parameter of the last sucessfull StartRecordingAudioFile(..) call. - // The return value is the number of bytes written to audioBuffer. - int32_t WriteWavData(OutStream& stream, - const int8_t* audioBuffer, - const size_t bufferLength); - - // Finalizes the WAV header so that it is correct if nothing more will be - // written to stream. - // Note: this API must be called before closing stream to ensure that the - // WAVE header is updated with the file size. Don't call this API - // if more samples are to be written to stream. - int32_t UpdateWavHeader(OutStream& stream); - - // Prepare for playing audio from stream. - // startPointMs and stopPointMs, unless zero, specify what part of the file - // should be read. From startPointMs ms to stopPointMs ms. - // freqInHz is the PCM sampling frequency. - // NOTE, allowed frequencies are 8000, 16000 and 32000 (Hz) - int32_t InitPCMReading(InStream& stream, - const uint32_t startPointMs = 0, - const uint32_t stopPointMs = 0, - const uint32_t freqInHz = 16000); - - // Put 10-60ms of audio data from stream into the audioBuffer depending on - // codec frame size. dataLengthInBytes indicates the size of audioBuffer. - // The return value is the number of bytes written to audioBuffer. - int32_t ReadPCMData(InStream& stream, int8_t* audioBuffer, - const size_t dataLengthInBytes); - - // Prepare for recording audio to stream. - // freqInHz is the PCM sampling frequency. - // NOTE, allowed frequencies are 8000, 16000 and 32000 (Hz) - int32_t InitPCMWriting(OutStream& stream, const uint32_t freqInHz = 16000); - - // Write one 10ms audio frame, i.e. the bufferLength first bytes of - // audioBuffer, to file. The audio frame size is determined by the freqInHz - // parameter of the last sucessfull InitPCMWriting(..) call. - // The return value is the number of bytes written to audioBuffer. - int32_t WritePCMData(OutStream& stream, - const int8_t* audioBuffer, - size_t bufferLength); - - // Prepare for playing audio from stream. - // startPointMs and stopPointMs, unless zero, specify what part of the file - // should be read. From startPointMs ms to stopPointMs ms. - int32_t InitCompressedReading(InStream& stream, - const uint32_t startPointMs = 0, - const uint32_t stopPointMs = 0); - - // Put 10-60ms of audio data from stream into the audioBuffer depending on - // codec frame size. dataLengthInBytes indicates the size of audioBuffer. - // The return value is the number of bytes written to audioBuffer. - int32_t ReadCompressedData(InStream& stream, - int8_t* audioBuffer, - const size_t dataLengthInBytes); - - // Prepare for recording audio to stream. - // codecInst specifies the encoding of the audio data. - int32_t InitCompressedWriting(OutStream& stream, - const CodecInst& codecInst); - - // Write one audio frame, i.e. the bufferLength first bytes of audioBuffer, - // to file. The audio frame size is determined by the codecInst.pacsize - // parameter of the last sucessfull InitCompressedWriting(..) call. - // The return value is the number of bytes written to stream. - // Note: bufferLength must be exactly one frame. - int32_t WriteCompressedData(OutStream& stream, - const int8_t* audioBuffer, - const size_t bufferLength); - - // Prepare for playing audio from stream. - // codecInst specifies the encoding of the audio data. - int32_t InitPreEncodedReading(InStream& stream, - const CodecInst& codecInst); - - // Put 10-60ms of audio data from stream into the audioBuffer depending on - // codec frame size. dataLengthInBytes indicates the size of audioBuffer. - // The return value is the number of bytes written to audioBuffer. - int32_t ReadPreEncodedData(InStream& stream, - int8_t* audioBuffer, - const size_t dataLengthInBytes); - - // Prepare for recording audio to stream. - // codecInst specifies the encoding of the audio data. - int32_t InitPreEncodedWriting(OutStream& stream, - const CodecInst& codecInst); - - // Write one audio frame, i.e. the bufferLength first bytes of audioBuffer, - // to stream. The audio frame size is determined by the codecInst.pacsize - // parameter of the last sucessfull InitPreEncodedWriting(..) call. - // The return value is the number of bytes written to stream. - // Note: bufferLength must be exactly one frame. - int32_t WritePreEncodedData(OutStream& stream, - const int8_t* inData, - const size_t dataLengthInBytes); - - // Set durationMs to the size of the file (in ms) specified by fileName. - // freqInHz specifies the sampling frequency of the file. - int32_t FileDurationMs(const char* fileName, - const FileFormats fileFormat, - const uint32_t freqInHz = 16000); - - // Return the number of ms that have been played so far. - uint32_t PlayoutPositionMs(); - - // Update codecInst according to the current audio codec being used for - // reading or writing. - int32_t codec_info(CodecInst& codecInst); - -private: - // Biggest WAV frame supported is 10 ms at 48kHz of 2 channel, 16 bit audio. - enum{WAV_MAX_BUFFER_SIZE = 480*2*2}; - - - int32_t InitWavCodec(uint32_t samplesPerSec, - uint32_t channels, - uint32_t bitsPerSample, - uint32_t formatTag); - - // Parse the WAV header in stream. - int32_t ReadWavHeader(InStream& stream); - - // Update the WAV header. freqInHz, bytesPerSample, channels, format, - // lengthInBytes specify characterists of the audio data. - // freqInHz is the sampling frequency. bytesPerSample is the sample size in - // bytes. channels is the number of channels, e.g. 1 is mono and 2 is - // stereo. format is the encode format (e.g. PCMU, PCMA, PCM etc). - // lengthInBytes is the number of bytes the audio samples are using up. - int32_t WriteWavHeader(OutStream& stream, - const uint32_t freqInHz, - const uint32_t bytesPerSample, - const uint32_t channels, - const uint32_t format, - const uint32_t lengthInBytes); - - // Put dataLengthInBytes of audio data from stream into the audioBuffer. - // The return value is the number of bytes written to audioBuffer. - int32_t ReadWavData(InStream& stream, uint8_t* audioBuffer, - const uint32_t dataLengthInBytes); - - // Update the current audio codec being used for reading or writing - // according to codecInst. - int32_t set_codec_info(const CodecInst& codecInst); - - struct WAVE_FMTINFO_header - { - int16_t formatTag; - int16_t nChannels; - int32_t nSamplesPerSec; - int32_t nAvgBytesPerSec; - int16_t nBlockAlign; - int16_t nBitsPerSample; - }; - // Identifiers for preencoded files. - enum MediaFileUtility_CodecType - { - kCodecNoCodec = 0, - kCodecIsac, - kCodecIsacSwb, - kCodecIsacLc, - kCodecL16_8Khz, - kCodecL16_16kHz, - kCodecL16_32Khz, - kCodecPcmu, - kCodecPcma, - kCodecIlbc20Ms, - kCodecIlbc30Ms, - kCodecG722, - kCodecG722_1_32Kbps, - kCodecG722_1_24Kbps, - kCodecG722_1_16Kbps, - kCodecG722_1c_48, - kCodecG722_1c_32, - kCodecG722_1c_24, - kCodecAmr, - kCodecAmrWb, - kCodecG729, - kCodecG729_1, - kCodecG726_40, - kCodecG726_32, - kCodecG726_24, - kCodecG726_16, - kCodecSpeex8Khz, - kCodecSpeex16Khz - }; - - // TODO (hellner): why store multiple formats. Just store either codec_info_ - // or _wavFormatObj and supply conversion functions. - WAVE_FMTINFO_header _wavFormatObj; - int32_t _dataSize; // Chunk size if reading a WAV file - // Number of bytes to read. I.e. frame size in bytes. May be multiple - // chunks if reading WAV. - int32_t _readSizeBytes; - - int32_t _id; - - uint32_t _stopPointInMs; - uint32_t _startPointInMs; - uint32_t _playoutPositionMs; - size_t _bytesWritten; - - CodecInst codec_info_; - MediaFileUtility_CodecType _codecId; - - // The amount of bytes, on average, used for one audio sample. - int32_t _bytesPerSample; - int32_t _readPos; - - // Only reading or writing can be enabled, not both. - bool _reading; - bool _writing; - - // Scratch buffer used for turning stereo audio to mono. - uint8_t _tempData[WAV_MAX_BUFFER_SIZE]; -}; -} // namespace webrtc -#endif // WEBRTC_MODULES_MEDIA_FILE_SOURCE_MEDIA_FILE_UTILITY_H_ |