1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 Mohamed Tarek
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <sys/types.h>
31 //#define DUMP_RAW_FRAMES
34 # define DEBUGF(message,args ...) printf
40 static unsigned char wav_header
[44]={
41 'R','I','F','F',// 0 - ChunkID
42 0,0,0,0, // 4 - ChunkSize (filesize-8)
43 'W','A','V','E',// 8 - Format
44 'f','m','t',' ',// 12 - SubChunkID
45 16,0,0,0, // 16 - SubChunk1ID // 16 for PCM
46 1,0, // 20 - AudioFormat (1=Uncompressed)
47 2,0, // 22 - NumChannels
48 0,0,0,0, // 24 - SampleRate in Hz
49 0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8)
50 4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8)
51 16,0, // 34 - BitsPerSample
52 'd','a','t','a',// 36 - Subchunk2ID
53 0,0,0,0 // 40 - Subchunk2Size
56 int open_wav(char* filename
) {
59 fd
=open(filename
,O_CREAT
|O_WRONLY
|O_TRUNC
,S_IRUSR
|S_IWUSR
);
61 res
= write(fd
,wav_header
,sizeof(wav_header
));
67 void close_wav(int fd
, RMContext
*rmctx
) {
70 int bytes_per_sample
= 2;
71 int samples_per_frame
= rmctx
->samples_pf_pc
;
72 int nb_channels
= rmctx
->nb_channels
;
73 int sample_rate
= rmctx
->sample_rate
;
74 int nb_frames
= rmctx
->audio_framesize
/rmctx
->block_align
* rmctx
->nb_packets
- 2; // first 2 frames have no valid audio; skipped in output
76 filesize
= samples_per_frame
*bytes_per_sample
*nb_frames
+44;
77 printf("Filesize = %d\n",filesize
);
81 wav_header
[4]=(x
&0xff);
82 wav_header
[5]=(x
&0xff00)>>8;
83 wav_header
[6]=(x
&0xff0000)>>16;
84 wav_header
[7]=(x
&0xff000000)>>24;
87 wav_header
[22]=nb_channels
;
90 wav_header
[24]=sample_rate
&0xff;
91 wav_header
[25]=(sample_rate
&0xff00)>>8;
92 wav_header
[26]=(sample_rate
&0xff0000)>>16;
93 wav_header
[27]=(sample_rate
&0xff000000)>>24;
96 x
=sample_rate
*bytes_per_sample
*nb_channels
;
97 wav_header
[28]=(x
&0xff);
98 wav_header
[29]=(x
&0xff00)>>8;
99 wav_header
[30]=(x
&0xff0000)>>16;
100 wav_header
[31]=(x
&0xff000000)>>24;
103 wav_header
[32]=rmctx
->block_align
;//2*rmctx->nb_channels;
110 wav_header
[40]=(x
&0xff);
111 wav_header
[41]=(x
&0xff00)>>8;
112 wav_header
[42]=(x
&0xff0000)>>16;
113 wav_header
[43]=(x
&0xff000000)>>24;
115 lseek(fd
,0,SEEK_SET
);
116 res
= write(fd
,wav_header
,sizeof(wav_header
));
120 int main(int argc
, char *argv
[])
123 int res
, datasize
,x
,i
;
125 #ifdef DUMP_RAW_FRAMES
129 int16_t outbuf
[2048];
132 uint32_t packet_count
;
137 memset(&q
,0,sizeof(COOKContext
));
138 memset(&rmctx
,0,sizeof(RMContext
));
139 memset(&pkt
,0,sizeof(RMPacket
));
142 DEBUGF("Incorrect number of arguments\n");
146 fd
= open(argv
[1],O_RDONLY
);
148 DEBUGF("Error opening file %s\n", argv
[1]);
152 fd_dec
= open_wav("output.wav");
154 DEBUGF("Error creating output file\n");
157 res
= real_parse_header(fd
, &rmctx
);
158 packet_count
= rmctx
.nb_packets
;
159 rmctx
.audio_framesize
= rmctx
.block_align
;
160 rmctx
.block_align
= rmctx
.sub_packet_size
;
161 fs
= rmctx
.audio_framesize
;
162 sps
= rmctx
.block_align
;
163 h
= rmctx
.sub_packet_h
;
164 cook_decode_init(&rmctx
,&q
);
165 DEBUGF("nb_frames = %d\n",nb_frames
);
169 packet_count
+= h
- (packet_count
% h
);
170 rmctx
.nb_packets
= packet_count
;
175 memset(pkt
.data
,0,sizeof(pkt
.data
));
176 rm_get_packet(fd
, &rmctx
, &pkt
);
177 DEBUGF("total frames = %d packet count = %d output counter = %d \n",rmctx
.audio_pkt_cnt
*(fs
/sps
), packet_count
,rmctx
.audio_pkt_cnt
);
178 for(i
= 0; i
< rmctx
.audio_pkt_cnt
*(fs
/sps
) ; i
++)
180 /* output raw audio frames that are sent to the decoder into separate files */
181 #ifdef DUMP_RAW_FRAMES
182 snprintf(filename
,sizeof(filename
),"dump%d.raw",++x
);
183 fd_out
= open(filename
,O_WRONLY
|O_CREAT
|O_APPEND
);
184 write(fd_out
,pkt
.data
+i
*sps
,sps
);
188 memcpy(inbuf
,pkt
.data
+i
*sps
,sps
);
189 nb_frames
= cook_decode_frame(&rmctx
,&q
, outbuf
, &datasize
, inbuf
, rmctx
.block_align
);
190 rmctx
.frame_number
++;
191 write(fd_dec
,outbuf
,datasize
);
193 packet_count
-= rmctx
.audio_pkt_cnt
;
194 rmctx
.audio_pkt_cnt
= 0;
196 close_wav(fd_dec
,&rmctx
);