LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/voice_engine - file_player.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 192 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/voice_engine/file_player.h"
      12             : 
      13             : #include "webrtc/common_audio/resampler/include/resampler.h"
      14             : #include "webrtc/common_types.h"
      15             : #include "webrtc/modules/media_file/media_file.h"
      16             : #include "webrtc/modules/media_file/media_file_defines.h"
      17             : #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
      18             : #include "webrtc/system_wrappers/include/logging.h"
      19             : #include "webrtc/typedefs.h"
      20             : #include "webrtc/voice_engine/coder.h"
      21             : 
      22             : namespace webrtc {
      23             : 
      24             : namespace {
      25             : 
      26             : class FilePlayerImpl : public FilePlayer {
      27             :  public:
      28             :   FilePlayerImpl(uint32_t instanceID, FileFormats fileFormat);
      29             :   ~FilePlayerImpl() override;
      30             : 
      31             :   int Get10msAudioFromFile(int16_t* outBuffer,
      32             :                            size_t* lengthInSamples,
      33             :                            int frequencyInHz) override;
      34             :   int32_t RegisterModuleFileCallback(FileCallback* callback) override;
      35             :   int32_t StartPlayingFile(const char* fileName,
      36             :                            bool loop,
      37             :                            uint32_t startPosition,
      38             :                            float volumeScaling,
      39             :                            uint32_t notification,
      40             :                            uint32_t stopPosition,
      41             :                            const CodecInst* codecInst) override;
      42             :   int32_t StartPlayingFile(InStream* sourceStream,
      43             :                            uint32_t startPosition,
      44             :                            float volumeScaling,
      45             :                            uint32_t notification,
      46             :                            uint32_t stopPosition,
      47             :                            const CodecInst* codecInst) override;
      48             :   int32_t StopPlayingFile() override;
      49             :   bool IsPlayingFile() const override;
      50             :   int32_t GetPlayoutPosition(uint32_t* durationMs) override;
      51             :   int32_t AudioCodec(CodecInst* audioCodec) const override;
      52             :   int32_t Frequency() const override;
      53             :   int32_t SetAudioScaling(float scaleFactor) override;
      54             : 
      55             :  private:
      56             :   int32_t SetUpAudioDecoder();
      57             : 
      58             :   const FileFormats _fileFormat;
      59             :   MediaFile& _fileModule;
      60             : 
      61             :   uint32_t _decodedLengthInMS;
      62             : 
      63             :   AudioCoder _audioDecoder;
      64             : 
      65             :   CodecInst _codec;
      66             :   int32_t _numberOf10MsPerFrame;
      67             :   int32_t _numberOf10MsInDecoder;
      68             : 
      69             :   Resampler _resampler;
      70             :   float _scaling;
      71             : };
      72             : 
      73           0 : FilePlayerImpl::FilePlayerImpl(const uint32_t instanceID,
      74           0 :                                const FileFormats fileFormat)
      75             :     : _fileFormat(fileFormat),
      76           0 :       _fileModule(*MediaFile::CreateMediaFile(instanceID)),
      77             :       _decodedLengthInMS(0),
      78             :       _audioDecoder(instanceID),
      79             :       _codec(),
      80             :       _numberOf10MsPerFrame(0),
      81             :       _numberOf10MsInDecoder(0),
      82             :       _resampler(),
      83           0 :       _scaling(1.0) {
      84           0 :   _codec.plfreq = 0;
      85           0 : }
      86             : 
      87           0 : FilePlayerImpl::~FilePlayerImpl() {
      88           0 :   MediaFile::DestroyMediaFile(&_fileModule);
      89           0 : }
      90             : 
      91           0 : int32_t FilePlayerImpl::Frequency() const {
      92           0 :   if (_codec.plfreq == 0) {
      93           0 :     return -1;
      94             :   }
      95             :   // Make sure that sample rate is 8,16 or 32 kHz. E.g. WAVE files may have
      96             :   // other sampling rates.
      97           0 :   if (_codec.plfreq == 11000) {
      98           0 :     return 16000;
      99           0 :   } else if (_codec.plfreq == 22000) {
     100           0 :     return 32000;
     101           0 :   } else if (_codec.plfreq == 44100) {
     102           0 :     return 32000;
     103           0 :   } else if (_codec.plfreq == 48000) {
     104           0 :     return 32000;
     105             :   } else {
     106           0 :     return _codec.plfreq;
     107             :   }
     108             : }
     109             : 
     110           0 : int32_t FilePlayerImpl::AudioCodec(CodecInst* audioCodec) const {
     111           0 :   *audioCodec = _codec;
     112           0 :   return 0;
     113             : }
     114             : 
     115           0 : int32_t FilePlayerImpl::Get10msAudioFromFile(int16_t* outBuffer,
     116             :                                              size_t* lengthInSamples,
     117             :                                              int frequencyInHz) {
     118           0 :   if (_codec.plfreq == 0) {
     119           0 :     LOG(LS_WARNING) << "Get10msAudioFromFile() playing not started!"
     120           0 :                     << " codec freq = " << _codec.plfreq
     121           0 :                     << ", wanted freq = " << frequencyInHz;
     122           0 :     return -1;
     123             :   }
     124             : 
     125           0 :   AudioFrame unresampledAudioFrame;
     126           0 :   if (STR_CASE_CMP(_codec.plname, "L16") == 0) {
     127           0 :     unresampledAudioFrame.sample_rate_hz_ = _codec.plfreq;
     128             : 
     129             :     // L16 is un-encoded data. Just pull 10 ms.
     130           0 :     size_t lengthInBytes = sizeof(unresampledAudioFrame.data_);
     131           0 :     if (_fileModule.PlayoutAudioData(
     132             :             reinterpret_cast<int8_t*>(unresampledAudioFrame.data_),
     133           0 :             lengthInBytes) == -1) {
     134             :       // End of file reached.
     135           0 :       return -1;
     136             :     }
     137           0 :     if (lengthInBytes == 0) {
     138           0 :       *lengthInSamples = 0;
     139           0 :       return 0;
     140             :     }
     141             :     // One sample is two bytes.
     142           0 :     unresampledAudioFrame.samples_per_channel_ = lengthInBytes >> 1;
     143             : 
     144             :   } else {
     145             :     // Decode will generate 10 ms of audio data. PlayoutAudioData(..)
     146             :     // expects a full frame. If the frame size is larger than 10 ms,
     147             :     // PlayoutAudioData(..) data should be called proportionally less often.
     148             :     int16_t encodedBuffer[MAX_AUDIO_BUFFER_IN_SAMPLES];
     149           0 :     size_t encodedLengthInBytes = 0;
     150           0 :     if (++_numberOf10MsInDecoder >= _numberOf10MsPerFrame) {
     151           0 :       _numberOf10MsInDecoder = 0;
     152           0 :       size_t bytesFromFile = sizeof(encodedBuffer);
     153           0 :       if (_fileModule.PlayoutAudioData(reinterpret_cast<int8_t*>(encodedBuffer),
     154           0 :                                        bytesFromFile) == -1) {
     155             :         // End of file reached.
     156           0 :         return -1;
     157             :       }
     158           0 :       encodedLengthInBytes = bytesFromFile;
     159             :     }
     160           0 :     if (_audioDecoder.Decode(&unresampledAudioFrame, frequencyInHz,
     161             :                              reinterpret_cast<int8_t*>(encodedBuffer),
     162             :                              encodedLengthInBytes) == -1) {
     163           0 :       return -1;
     164             :     }
     165             :   }
     166             : 
     167           0 :   size_t outLen = 0;
     168           0 :   if (_resampler.ResetIfNeeded(unresampledAudioFrame.sample_rate_hz_,
     169             :                                frequencyInHz, 1)) {
     170           0 :     LOG(LS_WARNING) << "Get10msAudioFromFile() unexpected codec.";
     171             : 
     172             :     // New sampling frequency. Update state.
     173           0 :     outLen = static_cast<size_t>(frequencyInHz / 100);
     174           0 :     memset(outBuffer, 0, outLen * sizeof(int16_t));
     175           0 :     return 0;
     176             :   }
     177           0 :   _resampler.Push(unresampledAudioFrame.data_,
     178             :                   unresampledAudioFrame.samples_per_channel_, outBuffer,
     179           0 :                   MAX_AUDIO_BUFFER_IN_SAMPLES, outLen);
     180             : 
     181           0 :   *lengthInSamples = outLen;
     182             : 
     183           0 :   if (_scaling != 1.0) {
     184           0 :     for (size_t i = 0; i < outLen; i++) {
     185           0 :       outBuffer[i] = (int16_t)(outBuffer[i] * _scaling);
     186             :     }
     187             :   }
     188           0 :   _decodedLengthInMS += 10;
     189           0 :   return 0;
     190             : }
     191             : 
     192           0 : int32_t FilePlayerImpl::RegisterModuleFileCallback(FileCallback* callback) {
     193           0 :   return _fileModule.SetModuleFileCallback(callback);
     194             : }
     195             : 
     196           0 : int32_t FilePlayerImpl::SetAudioScaling(float scaleFactor) {
     197           0 :   if ((scaleFactor >= 0) && (scaleFactor <= 2.0)) {
     198           0 :     _scaling = scaleFactor;
     199           0 :     return 0;
     200             :   }
     201           0 :   LOG(LS_WARNING) << "SetAudioScaling() non-allowed scale factor.";
     202           0 :   return -1;
     203             : }
     204             : 
     205           0 : int32_t FilePlayerImpl::StartPlayingFile(const char* fileName,
     206             :                                          bool loop,
     207             :                                          uint32_t startPosition,
     208             :                                          float volumeScaling,
     209             :                                          uint32_t notification,
     210             :                                          uint32_t stopPosition,
     211             :                                          const CodecInst* codecInst) {
     212           0 :   if (_fileFormat == kFileFormatPcm16kHzFile ||
     213           0 :       _fileFormat == kFileFormatPcm8kHzFile ||
     214           0 :       _fileFormat == kFileFormatPcm32kHzFile) {
     215             :     CodecInst codecInstL16;
     216           0 :     strncpy(codecInstL16.plname, "L16", 32);
     217           0 :     codecInstL16.pltype = 93;
     218           0 :     codecInstL16.channels = 1;
     219             : 
     220           0 :     if (_fileFormat == kFileFormatPcm8kHzFile) {
     221           0 :       codecInstL16.rate = 128000;
     222           0 :       codecInstL16.plfreq = 8000;
     223           0 :       codecInstL16.pacsize = 80;
     224             : 
     225           0 :     } else if (_fileFormat == kFileFormatPcm16kHzFile) {
     226           0 :       codecInstL16.rate = 256000;
     227           0 :       codecInstL16.plfreq = 16000;
     228           0 :       codecInstL16.pacsize = 160;
     229             : 
     230           0 :     } else if (_fileFormat == kFileFormatPcm32kHzFile) {
     231           0 :       codecInstL16.rate = 512000;
     232           0 :       codecInstL16.plfreq = 32000;
     233           0 :       codecInstL16.pacsize = 160;
     234             :     } else {
     235           0 :       LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
     236           0 :                     << "supported for PCM format.";
     237           0 :       return -1;
     238             :     }
     239             : 
     240           0 :     if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
     241           0 :                                           _fileFormat, &codecInstL16,
     242           0 :                                           startPosition, stopPosition) == -1) {
     243           0 :       LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
     244           0 :                       << "pcm file " << fileName;
     245           0 :       return -1;
     246             :     }
     247           0 :     SetAudioScaling(volumeScaling);
     248           0 :   } else if (_fileFormat == kFileFormatPreencodedFile) {
     249           0 :     if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
     250           0 :                                           _fileFormat, codecInst) == -1) {
     251           0 :       LOG(LS_WARNING) << "StartPlayingFile() failed to initialize "
     252           0 :                       << "pre-encoded file " << fileName;
     253           0 :       return -1;
     254             :     }
     255             :   } else {
     256           0 :     CodecInst* no_inst = NULL;
     257           0 :     if (_fileModule.StartPlayingAudioFile(fileName, notification, loop,
     258           0 :                                           _fileFormat, no_inst, startPosition,
     259           0 :                                           stopPosition) == -1) {
     260           0 :       LOG(LS_WARNING) << "StartPlayingFile() failed to initialize file "
     261           0 :                       << fileName;
     262           0 :       return -1;
     263             :     }
     264           0 :     SetAudioScaling(volumeScaling);
     265             :   }
     266           0 :   if (SetUpAudioDecoder() == -1) {
     267           0 :     StopPlayingFile();
     268           0 :     return -1;
     269             :   }
     270           0 :   return 0;
     271             : }
     272             : 
     273           0 : int32_t FilePlayerImpl::StartPlayingFile(InStream* sourceStream,
     274             :                                          uint32_t startPosition,
     275             :                                          float volumeScaling,
     276             :                                          uint32_t notification,
     277             :                                          uint32_t stopPosition,
     278             :                                          const CodecInst* codecInst) {
     279           0 :   if (_fileFormat == kFileFormatPcm16kHzFile ||
     280           0 :       _fileFormat == kFileFormatPcm32kHzFile ||
     281           0 :       _fileFormat == kFileFormatPcm8kHzFile) {
     282             :     CodecInst codecInstL16;
     283           0 :     strncpy(codecInstL16.plname, "L16", 32);
     284           0 :     codecInstL16.pltype = 93;
     285           0 :     codecInstL16.channels = 1;
     286             : 
     287           0 :     if (_fileFormat == kFileFormatPcm8kHzFile) {
     288           0 :       codecInstL16.rate = 128000;
     289           0 :       codecInstL16.plfreq = 8000;
     290           0 :       codecInstL16.pacsize = 80;
     291             : 
     292           0 :     } else if (_fileFormat == kFileFormatPcm16kHzFile) {
     293           0 :       codecInstL16.rate = 256000;
     294           0 :       codecInstL16.plfreq = 16000;
     295           0 :       codecInstL16.pacsize = 160;
     296             : 
     297           0 :     } else if (_fileFormat == kFileFormatPcm32kHzFile) {
     298           0 :       codecInstL16.rate = 512000;
     299           0 :       codecInstL16.plfreq = 32000;
     300           0 :       codecInstL16.pacsize = 160;
     301             :     } else {
     302           0 :       LOG(LS_ERROR) << "StartPlayingFile() sample frequency not "
     303           0 :                     << "supported for PCM format.";
     304           0 :       return -1;
     305             :     }
     306           0 :     if (_fileModule.StartPlayingAudioStream(
     307           0 :             *sourceStream, notification, _fileFormat, &codecInstL16,
     308           0 :             startPosition, stopPosition) == -1) {
     309           0 :       LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
     310           0 :                     << "playout.";
     311           0 :       return -1;
     312           0 :     }
     313             : 
     314           0 :   } else if (_fileFormat == kFileFormatPreencodedFile) {
     315           0 :     if (_fileModule.StartPlayingAudioStream(*sourceStream, notification,
     316           0 :                                             _fileFormat, codecInst) == -1) {
     317           0 :       LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
     318           0 :                     << "playout.";
     319           0 :       return -1;
     320             :     }
     321             :   } else {
     322           0 :     CodecInst* no_inst = NULL;
     323           0 :     if (_fileModule.StartPlayingAudioStream(*sourceStream, notification,
     324           0 :                                             _fileFormat, no_inst, startPosition,
     325           0 :                                             stopPosition) == -1) {
     326           0 :       LOG(LS_ERROR) << "StartPlayingFile() failed to initialize stream "
     327           0 :                     << "playout.";
     328           0 :       return -1;
     329             :     }
     330             :   }
     331           0 :   SetAudioScaling(volumeScaling);
     332             : 
     333           0 :   if (SetUpAudioDecoder() == -1) {
     334           0 :     StopPlayingFile();
     335           0 :     return -1;
     336             :   }
     337           0 :   return 0;
     338             : }
     339             : 
     340           0 : int32_t FilePlayerImpl::StopPlayingFile() {
     341           0 :   memset(&_codec, 0, sizeof(CodecInst));
     342           0 :   _numberOf10MsPerFrame = 0;
     343           0 :   _numberOf10MsInDecoder = 0;
     344           0 :   return _fileModule.StopPlaying();
     345             : }
     346             : 
     347           0 : bool FilePlayerImpl::IsPlayingFile() const {
     348           0 :   return _fileModule.IsPlaying();
     349             : }
     350             : 
     351           0 : int32_t FilePlayerImpl::GetPlayoutPosition(uint32_t* durationMs) {
     352           0 :   return _fileModule.PlayoutPositionMs(*durationMs);
     353             : }
     354             : 
     355           0 : int32_t FilePlayerImpl::SetUpAudioDecoder() {
     356           0 :   if ((_fileModule.codec_info(_codec) == -1)) {
     357           0 :     LOG(LS_WARNING) << "Failed to retrieve codec info of file data.";
     358           0 :     return -1;
     359             :   }
     360           0 :   if (STR_CASE_CMP(_codec.plname, "L16") != 0 &&
     361           0 :       _audioDecoder.SetDecodeCodec(_codec) == -1) {
     362           0 :     LOG(LS_WARNING) << "SetUpAudioDecoder() codec " << _codec.plname
     363           0 :                     << " not supported.";
     364           0 :     return -1;
     365             :   }
     366           0 :   _numberOf10MsPerFrame = _codec.pacsize / (_codec.plfreq / 100);
     367           0 :   _numberOf10MsInDecoder = 0;
     368           0 :   return 0;
     369             : }
     370             : 
     371             : }  // namespace
     372             : 
     373           0 : std::unique_ptr<FilePlayer> FilePlayer::CreateFilePlayer(
     374             :     uint32_t instanceID,
     375             :     FileFormats fileFormat) {
     376           0 :   switch (fileFormat) {
     377             :     case kFileFormatWavFile:
     378             :     case kFileFormatCompressedFile:
     379             :     case kFileFormatPreencodedFile:
     380             :     case kFileFormatPcm16kHzFile:
     381             :     case kFileFormatPcm8kHzFile:
     382             :     case kFileFormatPcm32kHzFile:
     383             :       // audio formats
     384             :       return std::unique_ptr<FilePlayer>(
     385           0 :           new FilePlayerImpl(instanceID, fileFormat));
     386             :     default:
     387           0 :       assert(false);
     388             :       return nullptr;
     389             :   }
     390             : }
     391             : 
     392             : }  // namespace webrtc

Generated by: LCOV version 1.13