2

I am trying to encode a PCM uncompressed Wav file using A law encoding. I have written a function which takes in the 16 bit PCM data and returns 8 bit encoded data..After encoding, my file does not play properly..I feel that there is something I am not doing correctly to handle the files.I have separated the header information of the file and written the same header to output file.

// Code for compressing data is below

short inbuff;
unsigned char outbuff;

while (!feof(inp))
{
    fread(inbuff, 2 , BUFSIZE, inp);
    for (i=0; i < BUFSIZE; ++i)
    {
        temp_16 = inbuff[i];
        temp_8 =  Lin2Alaw(temp_16);
        outbuff[i] = temp_8;
    }

    fwrite(outbuff, 1 , (BUFSIZE), out);
}
Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
Embed_Programmer
  • 35
  • 1
  • 1
  • 7
  • 1
    How are you playing it? How does it not play correctly? Are you writing it into a WAV file also? Setting the headers properly? – Sami Kuhmonen Dec 08 '15 at 09:58
  • yes , I am writing the compressed data to a new wav file. A wave file is created with distorted audio. The file header size is 58 bytes which i read first and write the same header to output file before starting compression. – Embed_Programmer Dec 08 '15 at 10:12
  • 2
    That is the problem. The header should contain information that the file is in a law format. If you write the same header, it will be understood as PCM data. – Sami Kuhmonen Dec 08 '15 at 10:16
  • Any idea which byte in the header is used to represent this? – Embed_Programmer Dec 08 '15 at 10:20
  • 1
    I also had one more question, so the file size after compression with A law is half the original size correct? – Embed_Programmer Dec 08 '15 at 10:22
  • Yes, a law is 8 bit encoding, so converting 16bit PCM to it will halve the file size, disregarding the header size of course – Sami Kuhmonen Dec 08 '15 at 10:23

3 Answers3

2

You are writing the data with the same header, which means that any audio program will think the data inside the WAV file is still PCM. Check the file format for WAV and change it accordingly.

Mainly you need to change audio format at 0x0014-0x0015 to a-law and other values also to mark the proper bytes per second, block size etc.

Easiest way to make sure they're correct might be to convert the file with an audio editor and then checking for the differences in the values.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
0

See the format of wave file is at

http://www.topherlee.com/software/pcm-tut-wavformat.html

Now check all bytes of header and make sure all information about bit rate,sample rate etc are correct.

If your code for compressing is correct then issue should be with header file only.

Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222
0

How did your code even compile when you are not using arrays? Even so, your use of feof isn't good, please see Why is “while ( !feof (file) )” always wrong?

#include <stdio.h>

#define BUFSIZE 512

int main(void) {
    short inbuff[BUFSIZE];                      // must be an array
    unsigned char outbuff[BUFSIZE];             // must be an array
    size_t bread, i;
    unsigned char temp_8;
    short temp_16;
    FILE *inp, *out;

    // ... open the file
    // ... transcribe the header

    // rewrite the data
    while ((bread = fread(inbuff, 2 , BUFSIZE, inp)) > 0)
    {
        for (i=0; i < bread; ++i)               // only the data actually read
        {
            temp_16 = inbuff[i];
            temp_8 =  Lin2Alaw(temp_16);
            outbuff[i] = temp_8;
        }
        fwrite(outbuff, 1 , bread, out);        // only the data actually read
    }

    // ... finish off and close the file

    return 0;
}

I notice too you are using signed short for the 16-bit data - should that be unsigned short?

Community
  • 1
  • 1
Weather Vane
  • 33,872
  • 7
  • 36
  • 56