Alexandre Lision | 8af73cb | 2013-12-10 14:11:20 -0500 | [diff] [blame] | 1 | #ifdef HAVE_CONFIG_H |
| 2 | #include "config.h" |
| 3 | #endif |
| 4 | |
| 5 | #include <speex/speex.h> |
| 6 | #include <stdio.h> |
| 7 | #include <stdlib.h> |
| 8 | #include <speex/speex_callbacks.h> |
| 9 | |
| 10 | #ifdef FIXED_DEBUG |
| 11 | extern long long spx_mips; |
| 12 | #endif |
| 13 | |
| 14 | #define FRAME_SIZE 160 |
| 15 | #include <math.h> |
| 16 | int main(int argc, char **argv) |
| 17 | { |
| 18 | char *inFile, *outFile, *bitsFile; |
| 19 | FILE *fin, *fout, *fbits=NULL; |
| 20 | short in_short[FRAME_SIZE]; |
| 21 | short out_short[FRAME_SIZE]; |
| 22 | int snr_frames = 0; |
| 23 | char cbits[200]; |
| 24 | int nbBits; |
| 25 | int i; |
| 26 | void *st; |
| 27 | void *dec; |
| 28 | SpeexBits bits; |
| 29 | spx_int32_t tmp; |
| 30 | int bitCount=0; |
| 31 | spx_int32_t skip_group_delay; |
| 32 | SpeexCallback callback; |
| 33 | |
| 34 | st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB)); |
| 35 | dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB)); |
| 36 | |
| 37 | /* BEGIN: You probably don't need the following in a real application */ |
| 38 | callback.callback_id = SPEEX_INBAND_CHAR; |
| 39 | callback.func = speex_std_char_handler; |
| 40 | callback.data = stderr; |
| 41 | speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); |
| 42 | |
| 43 | callback.callback_id = SPEEX_INBAND_MODE_REQUEST; |
| 44 | callback.func = speex_std_mode_request_handler; |
| 45 | callback.data = st; |
| 46 | speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback); |
| 47 | /* END of unnecessary stuff */ |
| 48 | |
| 49 | tmp=1; |
| 50 | speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp); |
| 51 | tmp=0; |
| 52 | speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp); |
| 53 | tmp=8; |
| 54 | speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp); |
| 55 | tmp=1; |
| 56 | speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp); |
| 57 | |
| 58 | /* Turn this off if you want to measure SNR (on by default) */ |
| 59 | tmp=1; |
| 60 | speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp); |
| 61 | speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp); |
| 62 | |
| 63 | speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay); |
| 64 | speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp); |
| 65 | skip_group_delay += tmp; |
| 66 | |
| 67 | if (argc != 4 && argc != 3) |
| 68 | { |
| 69 | fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc); |
| 70 | exit(1); |
| 71 | } |
| 72 | inFile = argv[1]; |
| 73 | fin = fopen(inFile, "rb"); |
| 74 | outFile = argv[2]; |
| 75 | fout = fopen(outFile, "wb+"); |
| 76 | if (argc==4) |
| 77 | { |
| 78 | bitsFile = argv[3]; |
| 79 | fbits = fopen(bitsFile, "wb"); |
| 80 | } |
| 81 | speex_bits_init(&bits); |
| 82 | while (!feof(fin)) |
| 83 | { |
| 84 | fread(in_short, sizeof(short), FRAME_SIZE, fin); |
| 85 | if (feof(fin)) |
| 86 | break; |
| 87 | speex_bits_reset(&bits); |
| 88 | |
| 89 | speex_encode_int(st, in_short, &bits); |
| 90 | nbBits = speex_bits_write(&bits, cbits, 200); |
| 91 | bitCount+=bits.nbBits; |
| 92 | |
| 93 | if (argc==4) |
| 94 | fwrite(cbits, 1, nbBits, fbits); |
| 95 | speex_bits_rewind(&bits); |
| 96 | |
| 97 | speex_decode_int(dec, &bits, out_short); |
| 98 | speex_bits_reset(&bits); |
| 99 | |
| 100 | fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout); |
| 101 | skip_group_delay = 0; |
| 102 | } |
| 103 | fprintf (stderr, "Total encoded size: %d bits\n", bitCount); |
| 104 | speex_encoder_destroy(st); |
| 105 | speex_decoder_destroy(dec); |
| 106 | speex_bits_destroy(&bits); |
| 107 | |
| 108 | #ifndef DISABLE_FLOAT_API |
| 109 | { |
| 110 | float sigpow,errpow,snr, seg_snr=0; |
| 111 | sigpow = 0; |
| 112 | errpow = 0; |
| 113 | |
| 114 | /* This code just computes SNR, so you don't need it either */ |
| 115 | rewind(fin); |
| 116 | rewind(fout); |
| 117 | |
| 118 | while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) |
| 119 | && |
| 120 | FRAME_SIZE == fread(out_short, sizeof(short), FRAME_SIZE,fout) ) |
| 121 | { |
| 122 | float s=0, e=0; |
| 123 | for (i=0;i<FRAME_SIZE;++i) { |
| 124 | s += (float)in_short[i] * in_short[i]; |
| 125 | e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]); |
| 126 | } |
| 127 | seg_snr += 10*log10((s+160)/(e+160)); |
| 128 | sigpow += s; |
| 129 | errpow += e; |
| 130 | snr_frames++; |
| 131 | } |
| 132 | snr = 10 * log10( sigpow / errpow ); |
| 133 | seg_snr /= snr_frames; |
| 134 | fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr); |
| 135 | |
| 136 | #ifdef FIXED_DEBUG |
| 137 | printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames)); |
| 138 | #endif |
| 139 | } |
| 140 | #endif |
| 141 | |
| 142 | fclose(fin); |
| 143 | fclose(fout); |
| 144 | |
| 145 | return 0; |
| 146 | } |