blob: b5a03339e29ecf456a8d800e1383803657122c38 [file] [log] [blame]
/*
* 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 "PCMFile.h"
#include <cctype>
#include <stdio.h>
#include <string.h>
#include "gtest/gtest.h"
#include "module_common_types.h"
namespace webrtc {
#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: ");
EXPECT_TRUE(fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin) != NULL);
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: ");
EXPECT_TRUE(fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin) != NULL);
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);
EXPECT_TRUE(fgets(tmpName, 10, stdin) != NULL);
WebRtc_UWord16 tmpFreq = (WebRtc_UWord16)atoi(tmpName);
if(tmpFreq > 0)
{
*frequencyHz = tmpFreq;
}
return 0;
}
void
PCMFile::Open(
const char* filename,
WebRtc_UWord16 frequency,
const char* mode,
bool autoRewind)
{
if ((_pcmFile = fopen(filename, mode)) == NULL)
{
printf("Cannot open file %s.\n", filename);
ADD_FAILURE() << "Unable to read file";
}
_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;
}
} // namespace webrtc