-Remove some unnecessary defines from rm.c.
[kugel-rb.git] / apps / codecs / libcook / main.c
blobb0b2829f254a089716f527025cb61c88e01b77b3
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <string.h>
28 #include "rm.h"
29 #include "cook.h"
31 //#define DUMP_RAW_FRAMES
32 #ifndef DEBUGF
33 # if 0
34 # define DEBUGF(message,args ...) printf
35 # else
36 # define DEBUGF(...)
37 # endif
38 #endif
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) {
57 int fd,res;
59 fd=open(filename,O_CREAT|O_WRONLY|O_TRUNC,S_IRUSR|S_IWUSR);
60 if (fd >= 0) {
61 res = write(fd,wav_header,sizeof(wav_header));
64 return(fd);
67 void close_wav(int fd, RMContext *rmctx) {
68 int x,res;
69 int filesize;
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);
79 // ChunkSize
80 x=filesize-8;
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;
86 // Number of channels
87 wav_header[22]=nb_channels;
89 // Samplerate
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;
95 // ByteRate
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;
102 // BlockAlign
103 wav_header[32]=rmctx->block_align;//2*rmctx->nb_channels;
105 // Bits per sample
106 wav_header[34]=16;
108 // Subchunk2Size
109 x=filesize-44;
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));
117 close(fd);
120 int main(int argc, char *argv[])
122 int fd, fd_dec;
123 int res, datasize,x,i;
124 int nb_frames = 0;
125 #ifdef DUMP_RAW_FRAMES
126 char filename[15];
127 int fd_out;
128 #endif
129 int16_t outbuf[2048];
130 uint8_t inbuf[1024];
131 uint16_t fs,sps,h;
132 uint32_t packet_count;
133 COOKContext q;
134 RMContext rmctx;
135 RMPacket pkt;
137 memset(&q,0,sizeof(COOKContext));
138 memset(&rmctx,0,sizeof(RMContext));
139 memset(&pkt,0,sizeof(RMPacket));
141 if (argc != 2) {
142 DEBUGF("Incorrect number of arguments\n");
143 return -1;
146 fd = open(argv[1],O_RDONLY);
147 if (fd < 0) {
148 DEBUGF("Error opening file %s\n", argv[1]);
149 return -1;
152 fd_dec = open_wav("output.wav");
153 if (fd_dec < 0) {
154 DEBUGF("Error creating output file\n");
155 return -1;
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);
166 x = 0;
167 if(packet_count % h)
169 packet_count += h - (packet_count % h);
170 rmctx.nb_packets = packet_count;
172 while(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);
185 close(fd_out);
186 #endif
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);
197 close(fd);
200 return 0;