Convert PCM to Ulaw

Convert PCM to Ulaw

將音檔格式從 pcm 編碼成 ulaw 格式


#include <sys\stat.h>
#include <stdio.h>
#include <malloc.h>
 
unsigned char Linear2Ulaw(register int linear_sample) ;
int Pcm2Ulaw(const char *, const char*);
int GetFileSize( const char * szFileName );
void AddPcmUlawHdr(FILE* fp , int nFileSize);
 
void main()
{
    Pcm2Ulaw("00057.pcm","00057.wav");
}
 
//
// This routine converts from linear to ulaw
// Input: Signed 16 bit linear sample
// Output: 8 bit ulaw sample
//
unsigned char Linear2Ulaw(register int linear_sample)
{
    static int exp_lut[256] = { 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
        4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
        5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
        5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
    register int sign, exponent, mantissa;
    register unsigned char ulaw_byte;
   
   
    // Convert the linear_sample into sign-magnitude.
    if (linear_sample <0)                    // get magnitude
    {
        if (linear_sample <-32635)
            linear_sample = -32635;            // clip magnitude (32635 = 32767-132) and dispose of -32768 problem
            linear_sample = -linear_sample;
            sign = 0x80;                        // define sign
    }
    else
    {
        if (linear_sample> 32635)
            linear_sample = 32635;          // clip magnitude (32635 = 32767-132)
            sign = 0x00;                    // define sign
    }
   
   
    // Convert from 15 bit unsigned linear to ulaw.
    linear_sample = linear_sample + 132;      // bias the magnitude
    exponent = exp_lut[linear_sample>> 7];    // exponent = floor(log2((abs(linear_sample)+132)/128))
    mantissa = (linear_sample>> (exponent + 3)) & 0x0F;
    ulaw_byte = (unsigned char)(sign | (exponent <<4) | mantissa);
    ulaw_byte = ~ulaw_byte;                                // invert bits
       
    //    if (ulaw_byte == 0) ulaw_byte = 0x02;          // optional CCITT (or MIL-STD?) trap        
    return ulaw_byte;
}
 
 
int Pcm2Ulaw(const char* szInFile , const char* szOutFile)
{
    FILE *fin = NULL , *fout = NULL;
    int nFileSize = 0;
    int nRet = 0;
    short *psBuff = NULL;
    unsigned char *pucBuff = NULL;
    int nSample = 0;
    int i = 0; 
   
    nFileSize = GetFileSize(szInFile);
    if(nFileSize <2)
        goto err_out;
 
    if( !(fin = fopen(szInFile,"rb")))
        goto err_out;
 
    if( !(fout = fopen(szOutFile,"wb")))
        goto err_out;
 
    psBuff  = (short*)malloc(nFileSize);
    pucBuff = (unsigned char*)malloc(nFileSize/sizeof(short));
   
    if(!psBuff)
        goto err_out;
    if(!pucBuff)
        goto err_out;
 
    fread(psBuff,nFileSize,1,fin);
 
    nSample = nFileSize / sizeof(short);
 
    for(i=0;i<nSample;i++) {
       pucBuff[i] = Linear2Ulaw(psBuff[i]);
    }
   
    AddPcmUlawHdr(fout, nSample * sizeof(unsigned char));
    fwrite(pucBuff,sizeof(unsigned char),nSample,fout);
 
    nRet = 1;
 
err_out:
    if(fin) fclose(fin);
    if(fout) fclose(fout);
    if(psBuff) free(psBuff);
    if(pucBuff) free(pucBuff);
    return nRet;
}
 
int GetFileSize( const char * szFileName )
{
  struct stat fileStat;
  int err = stat( szFileName, &fileStat );
  if (0 != err) return 0;
  return fileStat.st_size;
}
 
void AddPcmUlawHdr(FILE* fp , int nFileSize)
{
    int   nChunkSize = 0;
    int   nSubchunk1Size = 18;
    short sAudioFormat = 7;
    short sChannel = 1;
    short sBitsPerSampl = 8;
    short sReserve = 0;
    int   nSampleRate = 8000;
    int   nByteRate = nSampleRate * sChannel * sBitsPerSampl / 8;
    short sBlockAlign = sChannel * sBitsPerSampl / 8;
    int   nSubchunk2Size = 0;   
   
    nSubchunk2Size = nFileSize;
 
    fprintf(fp,"RIFF");                        //ChunkID : 4
    nChunkSize = nFileSize + 0x24;           
    fwrite(&nChunkSize,sizeof(int),1,fp);      //ChunkSize : 4
    fprintf(fp,"WAVE");         //Format : 4
    fprintf(fp,"fmt ");                        //Subchunk1ID : 4
    fwrite(&nSubchunk1Size,sizeof(int),1,fp);  //Subchunk1Size : 4
    fwrite(&sAudioFormat,sizeof(short),1,fp);  //AudioFormat : 2
    fwrite(&sChannel,sizeof(short),1,fp);      //NumChannels : 2
    fwrite(&nSampleRate,sizeof(int),1,fp);     //SampleRate : 4
    fwrite(&nByteRate,sizeof(int),1,fp);        //ByteRate : 4
    fwrite(&sBlockAlign,sizeof(short),1,fp);   //BlockAlign : 2
    fwrite(&sBitsPerSampl,sizeof(short),1,fp);  //BitsPerSample : 2
    fwrite(&sReserve,sizeof(short),1,fp);       // Reserved : 2
    fprintf(fp,"data");                        //Subchunk2ID : 4
    fwrite(&nSubchunk2Size,sizeof(int),1,fp);  //Subchunk2Size : 4 
}

 

Dotblogs 的標籤: ,