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>
28 #include "../librm/rm.h"
31 //#define DUMP_RAW_FRAMES
33 #define DATA_HEADER_SIZE 18 /* size of DATA chunk header in a rm file */
34 static unsigned char wav_header
[44]={
35 'R','I','F','F',// 0 - ChunkID
36 0,0,0,0, // 4 - ChunkSize (filesize-8)
37 'W','A','V','E',// 8 - Format
38 'f','m','t',' ',// 12 - SubChunkID
39 16,0,0,0, // 16 - SubChunk1ID // 16 for PCM
40 1,0, // 20 - AudioFormat (1=Uncompressed)
41 2,0, // 22 - NumChannels
42 0,0,0,0, // 24 - SampleRate in Hz
43 0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8)
44 4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8)
45 16,0, // 34 - BitsPerSample
46 'd','a','t','a',// 36 - Subchunk2ID
47 0,0,0,0 // 40 - Subchunk2Size
50 int open_wav(char* filename
) {
53 fd
=open(filename
,O_CREAT
|O_WRONLY
|O_TRUNC
,S_IRUSR
|S_IWUSR
);
55 res
= write(fd
,wav_header
,sizeof(wav_header
));
61 void close_wav(int fd
, RMContext
*rmctx
, COOKContext
*q
) {
64 int bytes_per_sample
= 2;
65 int samples_per_frame
= q
->samples_per_frame
;
66 int nb_channels
= rmctx
->nb_channels
;
67 int sample_rate
= rmctx
->sample_rate
;
68 int nb_frames
= rmctx
->audio_framesize
/rmctx
->block_align
* rmctx
->nb_packets
- 2; // first 2 frames have no valid audio; skipped in output
70 filesize
= samples_per_frame
*bytes_per_sample
*nb_frames
+44;
71 printf("Filesize = %d\n",filesize
);
75 wav_header
[4]=(x
&0xff);
76 wav_header
[5]=(x
&0xff00)>>8;
77 wav_header
[6]=(x
&0xff0000)>>16;
78 wav_header
[7]=(x
&0xff000000)>>24;
81 wav_header
[22]=nb_channels
;
84 wav_header
[24]=sample_rate
&0xff;
85 wav_header
[25]=(sample_rate
&0xff00)>>8;
86 wav_header
[26]=(sample_rate
&0xff0000)>>16;
87 wav_header
[27]=(sample_rate
&0xff000000)>>24;
90 x
=sample_rate
*bytes_per_sample
*nb_channels
;
91 wav_header
[28]=(x
&0xff);
92 wav_header
[29]=(x
&0xff00)>>8;
93 wav_header
[30]=(x
&0xff0000)>>16;
94 wav_header
[31]=(x
&0xff000000)>>24;
97 wav_header
[32]=rmctx
->block_align
;//2*rmctx->nb_channels;
104 wav_header
[40]=(x
&0xff);
105 wav_header
[41]=(x
&0xff00)>>8;
106 wav_header
[42]=(x
&0xff0000)>>16;
107 wav_header
[43]=(x
&0xff000000)>>24;
109 lseek(fd
,0,SEEK_SET
);
110 res
= write(fd
,wav_header
,sizeof(wav_header
));
114 int main(int argc
, char *argv
[])
119 #ifdef DUMP_RAW_FRAMES
123 int32_t outbuf
[2048];
125 uint32_t packet_count
;
130 memset(&q
,0,sizeof(COOKContext
));
131 memset(&rmctx
,0,sizeof(RMContext
));
132 memset(&pkt
,0,sizeof(RMPacket
));
135 DEBUGF("Incorrect number of arguments\n");
139 fd
= open(argv
[1],O_RDONLY
);
141 DEBUGF("Error opening file %s\n", argv
[1]);
145 /* copy the input rm file to a memory buffer */
146 uint8_t * filebuf
= (uint8_t *)calloc((int)filesize(fd
),sizeof(uint8_t));
147 res
= read(fd
,filebuf
,filesize(fd
));
149 fd_dec
= open_wav("output.wav");
151 DEBUGF("Error creating output file\n");
154 res
= real_parse_header(fd
, &rmctx
);
155 packet_count
= rmctx
.nb_packets
;
156 rmctx
.audio_framesize
= rmctx
.block_align
;
157 rmctx
.block_align
= rmctx
.sub_packet_size
;
158 fs
= rmctx
.audio_framesize
;
159 sps
= rmctx
.block_align
;
160 h
= rmctx
.sub_packet_h
;
161 cook_decode_init(&rmctx
,&q
);
163 /* change the buffer pointer to point at the first audio frame */
164 advance_buffer(&filebuf
, rmctx
.data_offset
+ DATA_HEADER_SIZE
);
167 rm_get_packet(&filebuf
, &rmctx
, &pkt
);
168 //DEBUGF("total frames = %d packet count = %d output counter = %d \n",rmctx.audio_pkt_cnt*(fs/sps), packet_count,rmctx.audio_pkt_cnt);
169 for(i
= 0; i
< rmctx
.audio_pkt_cnt
*(fs
/sps
) ; i
++)
171 /* output raw audio frames that are sent to the decoder into separate files */
172 #ifdef DUMP_RAW_FRAMES
173 snprintf(filename
,sizeof(filename
),"dump%d.raw",++x
);
174 fd_out
= open(filename
,O_WRONLY
|O_CREAT
|O_APPEND
);
175 write(fd_out
,pkt
.frames
[i
],sps
);
178 nb_frames
= cook_decode_frame(&rmctx
,&q
, outbuf
, &datasize
, pkt
.frames
[i
] , rmctx
.block_align
);
179 rmctx
.frame_number
++;
180 res
= write(fd_dec
,outbuf
,datasize
);
182 packet_count
-= rmctx
.audio_pkt_cnt
;
183 rmctx
.audio_pkt_cnt
= 0;
185 close_wav(fd_dec
, &rmctx
, &q
);