/* * Copyright (c) 2011 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 #include #include #include "PCMFile.h" #include "module_common_types.h" #define MAX_FILE_NAME_LENGTH_BYTE 500 PCMFile::PCMFile(): _pcmFile(NULL), _nSamples10Ms(160), _frequency(16000), _endOfFile(false), _autoRewind(false), _rewinded(false), _timestamp(0), _readStereo(false), _saveStereo(false) { _timestamp = (((WebRtc_UWord32)rand() & 0x0000FFFF) << 16) | ((WebRtc_UWord32)rand() & 0x0000FFFF); } /* PCMFile::~PCMFile() { if(_pcmFile != NULL) { fclose(_pcmFile); _pcmFile = NULL; } } */ WebRtc_Word16 PCMFile::ChooseFile( char* fileName, WebRtc_Word16 maxLen) { WebRtc_Word8 tmpName[MAX_FILE_NAME_LENGTH_BYTE]; //strcpy(_fileName, "in.pcm"); //printf("\n\nPlease enter the input file: "); fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin); tmpName[MAX_FILE_NAME_LENGTH_BYTE-1] = '\0'; WebRtc_Word16 n = 0; // removing leading spaces while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && (tmpName[n] != 0) && (n < MAX_FILE_NAME_LENGTH_BYTE)) { n++; } if(n > 0) { memmove(tmpName, &tmpName[n], MAX_FILE_NAME_LENGTH_BYTE - n); } //removing trailing spaces n = (WebRtc_Word16)(strlen(tmpName) - 1); if(n >= 0) { while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && (n >= 0)) { n--; } } if(n >= 0) { tmpName[n + 1] = '\0'; } WebRtc_Word16 len = (WebRtc_Word16)strlen(tmpName); if(len > maxLen) { return -1; } if(len > 0) { strncpy(fileName, tmpName, len+1); } return 0; } WebRtc_Word16 PCMFile::ChooseFile( char* fileName, WebRtc_Word16 maxLen, WebRtc_UWord16* frequencyHz) { WebRtc_Word8 tmpName[MAX_FILE_NAME_LENGTH_BYTE]; //strcpy(_fileName, "in.pcm"); //printf("\n\nPlease enter the input file: "); fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin); tmpName[MAX_FILE_NAME_LENGTH_BYTE-1] = '\0'; WebRtc_Word16 n = 0; // removing leading spaces while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && (tmpName[n] != 0) && (n < MAX_FILE_NAME_LENGTH_BYTE)) { n++; } if(n > 0) { memmove(tmpName, &tmpName[n], MAX_FILE_NAME_LENGTH_BYTE - n); } //removing trailing spaces n = (WebRtc_Word16)(strlen(tmpName) - 1); if(n >= 0) { while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && (n >= 0)) { n--; } } if(n >= 0) { tmpName[n + 1] = '\0'; } WebRtc_Word16 len = (WebRtc_Word16)strlen(tmpName); if(len > maxLen) { return -1; } if(len > 0) { strncpy(fileName, tmpName, len+1); } printf("Enter the sampling frequency (in Hz) of the above file [%u]: ", *frequencyHz); fgets(tmpName, 10, stdin); WebRtc_UWord16 tmpFreq = (WebRtc_UWord16)atoi(tmpName); if(tmpFreq > 0) { *frequencyHz = tmpFreq; } return 0; } void PCMFile::Open( char* filename, WebRtc_UWord16 frequency, const char* mode, bool autoRewind) { if ((_pcmFile = fopen(filename, mode)) == NULL) { printf("Cannot open file %s.\n", filename); throw "Unable to read file"; exit(1); } _frequency = frequency; _nSamples10Ms = (WebRtc_UWord16)(_frequency / 100); _autoRewind = autoRewind; _endOfFile = false; _rewinded = false; } WebRtc_Word32 PCMFile::SamplingFrequency() const { return _frequency; } WebRtc_UWord16 PCMFile::PayloadLength10Ms() const { return _nSamples10Ms; } WebRtc_Word32 PCMFile::Read10MsData( AudioFrame& audioFrame) { WebRtc_UWord16 noChannels = 1; if (_readStereo) { noChannels = 2; } WebRtc_Word32 payloadSize = (WebRtc_Word32)fread(audioFrame._payloadData, sizeof(WebRtc_UWord16), _nSamples10Ms*noChannels, _pcmFile); if (payloadSize < _nSamples10Ms*noChannels) { for (int k = payloadSize; k < _nSamples10Ms*noChannels; k++) { audioFrame._payloadData[k] = 0; } if(_autoRewind) { rewind(_pcmFile); _rewinded = true; } else { _endOfFile = true; } } audioFrame._payloadDataLengthInSamples = _nSamples10Ms; audioFrame._frequencyInHz = _frequency; audioFrame._audioChannel = noChannels; audioFrame._timeStamp = _timestamp; _timestamp += _nSamples10Ms; return _nSamples10Ms; } void PCMFile::Write10MsData( AudioFrame& audioFrame) { if(audioFrame._audioChannel == 1) { if(!_saveStereo) { fwrite(audioFrame._payloadData, sizeof(WebRtc_UWord16), audioFrame._payloadDataLengthInSamples, _pcmFile); } else { WebRtc_Word16* stereoAudio = new WebRtc_Word16[2 * audioFrame._payloadDataLengthInSamples]; int k; for(k = 0; k < audioFrame._payloadDataLengthInSamples; k++) { stereoAudio[k<<1] = audioFrame._payloadData[k]; stereoAudio[(k<<1) + 1] = audioFrame._payloadData[k]; } fwrite(stereoAudio, sizeof(WebRtc_Word16), 2*audioFrame._payloadDataLengthInSamples, _pcmFile); delete [] stereoAudio; } } else { fwrite(audioFrame._payloadData, sizeof(WebRtc_Word16), audioFrame._audioChannel * audioFrame._payloadDataLengthInSamples, _pcmFile); } } void PCMFile::Write10MsData( WebRtc_Word16* playoutBuffer, WebRtc_UWord16 playoutLengthSmpls) { fwrite(playoutBuffer, sizeof(WebRtc_UWord16), playoutLengthSmpls, _pcmFile); } void PCMFile::Close() { fclose(_pcmFile); _pcmFile = NULL; } void PCMFile::Rewind() { rewind(_pcmFile); _endOfFile = false; } bool PCMFile::Rewinded() { return _rewinded; } void PCMFile::SaveStereo( bool saveStereo) { _saveStereo = saveStereo; } void PCMFile::ReadStereo( bool readStereo) { _readStereo = readStereo; }