Technical discussions related to Speech Coding (all itu and other vocoders, ACELP, CELP, AMR, etc)
|
Hi All, I am testing out the G.711 code given below with a wav file but the wave file given out by the program is the same size and also it does not play as well.what could be the problem?I am using turbo C ide for compiling.is there a different way to do that? /* this is Encoder-main file of G.711(pcm)*/ #include <stdio.h> #include <stdlib.h> #include "funct.c" #include "tab.h" #define SAMP 1024 unsigned char linear2ulaw(short pcm_val); short ulaw2linear(unsigned char u_val); int main() { short pcm_val[SAMP]; unsigned char inp[SAMP]; short i, count, outbuf[SAMP]; FILE *infile,*outfile; infile = fopen("y.wav","rb"); outfile = fopen("yout.wav","wb"); do { count = fread(pcm_val,sizeof(short),SAMP,infile); for (i=0; i<count;++i) { inp[i]=linear2ulaw(pcm_val[i]); outbuf[i] = ulaw2linear(inp[i]); } if (fwrite(outbuf, sizeof(short), count, outfile) != count) { fprintf(stderr,"Write Access Error, File"); return 1;} } while (count == SAMP); fclose(infile); fclose(outfile); return 0; } -------------------------------- /*this is the funct.c file*/ #include <stdio.h> #include "tab.h" static short search(short val, short *table, short size) { short i; for (i = 0; i < size; i++) { if (val <= *table++) return (i); } return (size); } static short seg_end[8] = {0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF}; /* * linear2ulaw() - Convert a linear PCM value to u-law * * In order to simplify the encoding process, the original linear magnitude * is biased by adding 33 which shifts the encoding range from (0 - 8158) to * (33 - 8191). The result can be seen in the following encoding table: * * Biased Linear Input Code Compressed Code * ------------------------ --------------- * 00000001wxyza 000wxyz * 0000001wxyzab 001wxyz * 000001wxyzabc 010wxyz * 00001wxyzabcd 011wxyz * 0001wxyzabcde 100wxyz * 001wxyzabcdef 101wxyz * 01wxyzabcdefg 110wxyz * 1wxyzabcdefgh 111wxyz * * Each biased linear code has a leading 1 which identifies the segment * number. The value of the segment number is equal to 7 minus the number * of leading 0's. The quantization interval is directly available as the * four bits wxyz. * The trailing bits (a - h) are ignored. * * Ordinarily the complement of the resulting code word is used for * transmission, and so the code word is complemented before it is returned. * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ unsigned char linear2ulaw(short pcm_val) /*2's complement(16-bit range)*/ { short mask; short seg; unsigned char uval; /* Get the sign and the magnitude of the value. */ pcm_val = pcm_val >> 2; if (pcm_val < 0) { pcm_val = -pcm_val; mask = 0x7F; } else { mask = 0xFF; } if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ pcm_val += (BIAS >> 2); /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_end, 8); /* * Combine the sign, segment, quantization bits; * and complement the code word. */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); return (uval ^ mask); } } /* * ulaw2linear() - Convert a u-law value to 16-bit linear PCM * * First, a biased linear code is derived from the code word. An unbiased * output can then be obtained by subtracting 33 from the biased code. * * Note that this function expects to be passed the complement of the * original code word. This is in keeping with ISDN conventions. */ short ulaw2linear(unsigned char u_val) { short t; /* Complement to obtain normal u-law value. */ u_val = ~u_val; /* * Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias. */ t = ((u_val & QUANT_MASK) << 3) + BIAS; t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); } ------------------------------------ /* this is the header file tab.h*/ #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ #define BIAS (0x84) #define CLIP 8159 |
|
|
|
HI Samad, The problem is very simple. What you are doing is feeding a "wav" file as input and writing the processed file back into wav format. Whats happening here is, the CODEC is processing the input along with the "wave header".The processing will corrupt the header information. And you are assuming that it writes back the same "wav" format which is not the case. So what you need to do is convert WAV file to a BINary file by stripping off the Header info and apply this as input to the Codec.Also write the output file in "out.Bin" format. After running your program, just convert the "out.BIN" to a "out.wav" file. The conversions can be done using utilities like wav2bin.exe or bin2wav.exe. The code is doing "linear2ulaw" and back from "ulaw2linear" So it is obvious that the sizes of input and output are equal. BTW are you really able to play ur "yout.wav"?? I dont think so..... Hope this answers your problem. Thanks and Regards, BhanuPrakash P. "As a matter of fact, it is the grey matter what matters not the money matters." - Bhanu Prakash --- samad_ma <> wrote: > Hi All, > I am testing out the G.711 code given below with a > wav file but the > wave file given out by the program is the same size > and also it does > not play as well.what could be the problem?I am > using turbo C ide for > compiling.is there a different way to do that? > > /* this is Encoder-main file of G.711(pcm)*/ > > #include <stdio.h> > #include <stdlib.h> > #include "funct.c" > #include "tab.h" > > #define SAMP 1024 > > unsigned char linear2ulaw(short pcm_val); > short ulaw2linear(unsigned char u_val); > > int main() > { > short pcm_val[SAMP]; > unsigned char inp[SAMP]; > short i, count, outbuf[SAMP]; > > FILE *infile,*outfile; > > infile = fopen("y.wav","rb"); > outfile = fopen("yout.wav","wb"); > > do > { > count = > fread(pcm_val,sizeof(short),SAMP,infile); > > for (i=0; i<count;++i) { > inp[i]=linear2ulaw(pcm_val[i]); > outbuf[i] = ulaw2linear(inp[i]); > } > > if (fwrite(outbuf, sizeof(short), count, > outfile) != count) > { fprintf(stderr,"Write Access Error, > File"); return 1;} > } while (count == SAMP); > > fclose(infile); > fclose(outfile); > return 0; > } > -------------------------------- > /*this is the funct.c file*/ > #include <stdio.h> > #include "tab.h" > static short search(short val, short *table, short > size) > { > short i; > > for (i = 0; i < size; i++) { > if (val <= *table++) > return (i); > } > return (size); > } > static short seg_end[8] = {0x3F, 0x7F, 0xFF, 0x1FF, > 0x3FF, 0x7FF, > 0xFFF, 0x1FFF}; > /* > * linear2ulaw() - Convert a linear PCM value to > u-law > * > * In order to simplify the encoding process, the > original linear > magnitude > * is biased by adding 33 which shifts the encoding > range from (0 - > 8158) to > * (33 - 8191). The result can be seen in the > following encoding > table: > * > * Biased Linear Input Code Compressed Code > * ------------------------ --------------- > * 00000001wxyza 000wxyz > * 0000001wxyzab 001wxyz > * 000001wxyzabc 010wxyz > * 00001wxyzabcd 011wxyz > * 0001wxyzabcde 100wxyz > * 001wxyzabcdef 101wxyz > * 01wxyzabcdefg 110wxyz > * 1wxyzabcdefgh 111wxyz > * > * Each biased linear code has a leading 1 which > identifies the > segment > * number. The value of the segment number is equal > to 7 minus the > number > * of leading 0's. The quantization interval is > directly available as > the > * four bits wxyz. * The trailing bits (a - h) are > ignored. > * > * Ordinarily the complement of the resulting code > word is used for > * transmission, and so the code word is > complemented before it is > returned. > * > * For further information see John C. Bellamy's > Digital Telephony, > 1982, > * John Wiley & Sons, pps 98-111 and 472-476. > */ > > unsigned char linear2ulaw(short pcm_val) /*2's > complement(16-bit > range)*/ > { > short mask; > short seg; > unsigned char uval; > > /* Get the sign and the magnitude of the value. */ > pcm_val = pcm_val >> 2; > if (pcm_val < 0) { > pcm_val = -pcm_val; > mask = 0x7F; > } else { > mask = 0xFF; > } > if ( pcm_val > CLIP ) pcm_val = CLIP; /* > clip the > magnitude */ > pcm_val += (BIAS >> 2); > > /* Convert the scaled magnitude to segment number. > */ > seg = search(pcm_val, seg_end, 8); > > /* > * Combine the sign, segment, quantization bits; > * and complement the code word. > */ > if (seg >= 8) /* out of range, return maximum > value. */ > return (unsigned char) (0x7F ^ mask); > else { > uval = (unsigned char) (seg << 4) | ((pcm_val >> > (seg > + 1)) & 0xF); > return (uval ^ mask); > } > > } > > /* > * ulaw2linear() - Convert a u-law value to 16-bit > linear PCM > * > * First, a biased linear code is derived from the > code word. An > unbiased > * output can then be obtained by subtracting 33 > from the biased code. > * > * Note that this function expects to be passed the > complement of the > * original code word. This is in keeping with ISDN > conventions. > */ > > short ulaw2linear(unsigned char u_val) > { > short t; > > /* Complement to obtain normal u-law value. */ > u_val = ~u_val; > > /* > * Extract and bias the quantization bits. Then > * shift up by the segment number and subtract out > the bias. > */ > t = ((u_val & QUANT_MASK) << 3) + BIAS; > t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; === message truncated === __________________________________________________ |