/************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * * Copyright (C) 2007 Thom Johansen * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ***************************************************************************/ #include #include #include #include "string.h" #include "rbspeex.h" #define USAGE_TEXT \ "Usage: rbspeexdec infile outfile\n"\ "rbspeexdec outputs mono 16 bit 16 kHz WAV files.\n"\ "WARNING: This tool will only decode files made with rbspeexenc!\n" int main(int argc, char **argv) { FILE *fin, *fout; char *indata; short out[640]; /* max frame size (UWB) */ unsigned char wavhdr[44]; int numbytes; void *st; /* decoder state */ SpeexBits bits; int i, tmp, lookahead, frame_size; unsigned int samples = 0; long insize; if (argc < 3) { printf(USAGE_TEXT); return 1; } /* Rockbox speex streams are always assumed to be WB */ st = speex_decoder_init(&speex_wb_mode); /* Set the perceptual enhancement on (is default, but doesn't hurt) */ tmp = 1; speex_decoder_ctl(st, SPEEX_SET_ENH, &tmp); speex_decoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead); speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size); if ((fin = fopen(argv[1], "rb")) == NULL) { printf("Error: could not open input file\n"); return 1; } if ((fout = fopen(argv[2], "wb")) == NULL) { printf("Error: could not open output file\n"); return 1; } /* slurp infile */ fseek(fin, 0, SEEK_END); insize = ftell(fin); fseek(fin, 0, SEEK_SET); indata = malloc(insize); fread(indata, 1, insize, fin); fclose(fin); /* fill in wav header */ strcpy(wavhdr, "RIFF"); strcpy(wavhdr + 8, "WAVEfmt "); put_uint_le(16, wavhdr + 16); put_ushort_le(1, wavhdr + 20); /* PCM data */ put_ushort_le(1, wavhdr + 22); /* mono */ put_uint_le(16000, wavhdr + 24); /* 16000 Hz */ put_uint_le(16000*2, wavhdr + 28); /* chan*sr*bbs/8 */ put_ushort_le(2, wavhdr + 32); /* chan*bps/8 */ put_ushort_le(16, wavhdr + 34); /* bits per sample */ strcpy(wavhdr + 36, "data"); fwrite(wavhdr, 1, 44, fout); /* write header */ /* make bit buffer use our own buffer */ speex_bits_set_bit_buffer(&bits, indata, insize); while (speex_decode_int(st, &bits, out) == 0) { /* if no error, write decoded audio */ fwrite(out + lookahead, sizeof(short), frame_size - lookahead, fout); samples += frame_size - lookahead; lookahead = 0; /* only skip samples at the start */ } speex_decoder_destroy(st); /* now fill in the values in the wav header we didn't have at the start */ fseek(fout, 4, SEEK_SET); put_uint_le(36 + samples*2, wavhdr); /* header size + data size */ fwrite(wavhdr, 1, 4, fout); fseek(fout, 40, SEEK_SET); put_uint_le(samples*2, wavhdr); /* data size */ fwrite(wavhdr, 1, 4, fout); fclose(fout); free(indata); return 0; }