#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include "g711.h"

using namespace std;

char dataBuffer[1000000];
char compressedDataBuffer[1000000];
char outDataBuffer[1000000];

void printLittleEndian4String(unsigned int x)
{
    char* ptr;
    int i;

    ptr=(char*)&x;

    for(i=0; i<4; i++)
    {
        printf("%c", *ptr++);
    }
}


int main(int argc, char *argv[])
{
    
    ifstream inFile;
    ofstream outFile;

    char filename[260];
    char filenameOut[260];
    void* buff;
    int length;
    int i, l, j;

    unsigned int riff;
    unsigned int chunkSize;
    unsigned int wave;
    unsigned int fmt;
    unsigned int subChunk1Size;
    unsigned short AudioFormat;
    unsigned short NumChannels;
    unsigned int SampleRate;
    unsigned int ByteRate;
    unsigned short BlockAlign;
    unsigned short BitsPerSample;
    unsigned int data;


    if(argc<=1)
    {

        printf("Usage: <wave2hex> <filename>");
    } else
    {

    sprintf(filename, "%s.wav", argv[1]);
    inFile.open(filename, ifstream::in | ifstream::binary);

    if(inFile.good())
    {

    inFile.seekg(0, ios::beg);
    printf("Opened File: %s.\n", filename);
    
    length=1000000;
    inFile.read(dataBuffer, length);
    i=inFile.gcount();
    printf("Read: %d Bytes from wav file: %s \n", i, filename);
    printf("Parsing...\n");
    buff=(void*)&dataBuffer[0];
    riff=*(unsigned int*)buff;
    printf("Riff            : ", riff);
    printLittleEndian4String(riff);
    printf("\n");
    buff=(void*)&dataBuffer[4];
    chunkSize=*(unsigned int*)buff;
    printf("ChunkSize       : 0x%8.8X \n", chunkSize);
    buff=(void*)&dataBuffer[8];
    wave=*(unsigned int*)buff;
    printf("Wave            : ");
    printLittleEndian4String(wave);
    printf("\n");
    buff=(void*)&dataBuffer[12];
    fmt=*(unsigned int*)buff;
    printf("Fmt             : ");
    printLittleEndian4String(fmt);
    printf("\n");
    buff=(void*)&dataBuffer[16];
    subChunk1Size=*(unsigned int*)buff;
    printf("SubChunk1Size   : 0x%8.8X \n", subChunk1Size);
    buff=(void*)&dataBuffer[20];
    AudioFormat=*(unsigned short*)buff;
    printf("Audio Format    : %d \n", AudioFormat);
    buff=(void*)&dataBuffer[22];
    NumChannels=*(unsigned short*)buff;
    printf("Num Channels    : %d \n", NumChannels);
    buff=(void*)&dataBuffer[24];
    SampleRate=*(unsigned int*)buff;
    printf("Sample Rate     : %d \n", SampleRate);
    buff=(void*)&dataBuffer[28];
    ByteRate=*(unsigned int*)buff;
    printf("Byte Rate       : %d \n", ByteRate);
    buff=(void*)&dataBuffer[32];
    BlockAlign=*(unsigned short*)buff;
    printf("Block Align     : %d \n", BlockAlign);
    buff=(void*)&dataBuffer[34];
    BitsPerSample=*(unsigned short*)buff;
    printf("Bits Per Sample : %d \n", BitsPerSample);
    buff=(void*)&dataBuffer[36];
    data=*(unsigned int*)buff;
    printf("Data            : ");
    printLittleEndian4String(data);
    printf("\n");

    l=(chunkSize-44)/2;
    alaw_compress(l, (short*)&dataBuffer[44], (unsigned char*)&compressedDataBuffer[0]);

    printf("Creating Output A-Law Compressed File.\n");
    sprintf(filenameOut, "%s.alc", argv[1]);
    outFile.open(filenameOut, ofstream::out | ofstream::binary);
    if(outFile.good())
    {
    printf("Output File Good: %s.\n", filenameOut);
    outFile.write(compressedDataBuffer, l);
    } else
    printf("Output File Bad!\n");
/*
    printf("Begin Data.\n");

    printf(" indata[%d]= \n", ((chunkSize-44)/2));
    j=0;
    l=0;
    for(i=0; i< (chunkSize-44)/2; i++)
    {
    buff=(void*)&dataBuffer[44+i*2];
    printf("0x%4.4X, ", 0xFFFF & (*(short*)buff));
    j++;
    if(j==8){ j=0; printf("\n"); }
    l++;
    }
    printf("Done. Samples: %d\n", l);

    printf("Begin Compressed Data.\n");

    alaw_compress(l, (short*)&dataBuffer[44], (short*)&compressedDataBuffer[0]);

    printf(" compressedData[%d]= \n", ((chunkSize-44)/2));
    j=0;
    l=0;
    for(i=0; i< (chunkSize-44)/2; i++)
    {
        buff=(void*)&compressedDataBuffer[i*2];
        printf("0x%2.2X, ", 0xFF & (*(short*)buff));
        j++;
        if(j==8){ j=0; printf("\n"); }
        l++;
    }
    printf("Done. Samples: %d\n", l);

    printf("Begin Expanded Data.\n");

    alaw_expand(l, (short*)&compressedDataBuffer[0], (short*)&outDataBuffer[0]);

    printf(" expandedData[%d]= \n", ((chunkSize-44)/2));
    j=0;
    l=0;
    for(i=0; i< (chunkSize-44)/2; i++)
    {
        buff=(void*)&outDataBuffer[i*2];
        printf("0x%4.4X, ", 0xFFFF & (*(short*)buff));
        j++;
        if(j==8){ j=0; printf("\n"); }
        l++;
    }
    printf("Done. Samples: %d\n", l);

*/

    outFile.close();
    inFile.close();
    } else
    {
    printf("Cannot Open file: %s.\n", filename);
    }
    }

    return 0;
}
