
/*
 *  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"

#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(
    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;
}
