diff options
author | Mohamed Tarek <mt@rockbox.org> | 2009-05-22 20:23:38 +0000 |
---|---|---|
committer | Mohamed Tarek <mt@rockbox.org> | 2009-05-22 20:23:38 +0000 |
commit | b63028d80ae665688a2202a2eaeb2e01e10ab520 (patch) | |
tree | 762cec22804a554c97983ccbe4a818eca899d528 | |
parent | 694b3b734f8b1cddb323b29e74929a35bb5cd9ef (diff) | |
download | rockbox-b63028d80ae665688a2202a2eaeb2e01e10ab520.tar.gz rockbox-b63028d80ae665688a2202a2eaeb2e01e10ab520.zip |
Modify the test program to read audio frames from a memory buffer rather
than a file descriptor, to make the decoding process as much similar
as to how it should be in rockbox.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21042 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/libcook/main.c | 18 | ||||
-rw-r--r-- | apps/codecs/libcook/rm.c | 73 | ||||
-rw-r--r-- | apps/codecs/libcook/rm.h | 5 |
3 files changed, 86 insertions, 10 deletions
diff --git a/apps/codecs/libcook/main.c b/apps/codecs/libcook/main.c index b0b2829f25..3557b15524 100644 --- a/apps/codecs/libcook/main.c +++ b/apps/codecs/libcook/main.c | |||
@@ -37,6 +37,7 @@ | |||
37 | # endif | 37 | # endif |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #define DATA_HEADER_SIZE 18 /* size of DATA chunk header in a rm file */ | ||
40 | static unsigned char wav_header[44]={ | 41 | static unsigned char wav_header[44]={ |
41 | 'R','I','F','F',// 0 - ChunkID | 42 | 'R','I','F','F',// 0 - ChunkID |
42 | 0,0,0,0, // 4 - ChunkSize (filesize-8) | 43 | 0,0,0,0, // 4 - ChunkSize (filesize-8) |
@@ -127,7 +128,6 @@ int main(int argc, char *argv[]) | |||
127 | int fd_out; | 128 | int fd_out; |
128 | #endif | 129 | #endif |
129 | int16_t outbuf[2048]; | 130 | int16_t outbuf[2048]; |
130 | uint8_t inbuf[1024]; | ||
131 | uint16_t fs,sps,h; | 131 | uint16_t fs,sps,h; |
132 | uint32_t packet_count; | 132 | uint32_t packet_count; |
133 | COOKContext q; | 133 | COOKContext q; |
@@ -149,6 +149,10 @@ int main(int argc, char *argv[]) | |||
149 | return -1; | 149 | return -1; |
150 | } | 150 | } |
151 | 151 | ||
152 | /* copy the input rm file to a memory buffer */ | ||
153 | uint8_t * filebuf = (uint8_t *)calloc((int)filesize(fd),sizeof(uint8_t)); | ||
154 | read(fd,filebuf,filesize(fd)); | ||
155 | |||
152 | fd_dec = open_wav("output.wav"); | 156 | fd_dec = open_wav("output.wav"); |
153 | if (fd_dec < 0) { | 157 | if (fd_dec < 0) { |
154 | DEBUGF("Error creating output file\n"); | 158 | DEBUGF("Error creating output file\n"); |
@@ -169,11 +173,12 @@ int main(int argc, char *argv[]) | |||
169 | packet_count += h - (packet_count % h); | 173 | packet_count += h - (packet_count % h); |
170 | rmctx.nb_packets = packet_count; | 174 | rmctx.nb_packets = packet_count; |
171 | } | 175 | } |
176 | |||
177 | /* change the buffer pointer to point at the first audio frame */ | ||
178 | advance_buffer(&filebuf, rmctx.data_offset+ DATA_HEADER_SIZE); | ||
172 | while(packet_count) | 179 | while(packet_count) |
173 | { | 180 | { |
174 | 181 | rm_get_packet_membuf(&filebuf, &rmctx, &pkt); | |
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); | 182 | 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++) | 183 | for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) |
179 | { | 184 | { |
@@ -181,12 +186,11 @@ int main(int argc, char *argv[]) | |||
181 | #ifdef DUMP_RAW_FRAMES | 186 | #ifdef DUMP_RAW_FRAMES |
182 | snprintf(filename,sizeof(filename),"dump%d.raw",++x); | 187 | snprintf(filename,sizeof(filename),"dump%d.raw",++x); |
183 | fd_out = open(filename,O_WRONLY|O_CREAT|O_APPEND); | 188 | fd_out = open(filename,O_WRONLY|O_CREAT|O_APPEND); |
184 | write(fd_out,pkt.data+i*sps,sps); | 189 | write(fd_out,pkt.frames[i],sps); |
185 | close(fd_out); | 190 | close(fd_out); |
186 | #endif | 191 | #endif |
187 | 192 | ||
188 | memcpy(inbuf,pkt.data+i*sps,sps); | 193 | nb_frames = cook_decode_frame(&rmctx,&q, outbuf, &datasize, pkt.frames[i] , rmctx.block_align); |
189 | nb_frames = cook_decode_frame(&rmctx,&q, outbuf, &datasize, inbuf , rmctx.block_align); | ||
190 | rmctx.frame_number++; | 194 | rmctx.frame_number++; |
191 | write(fd_dec,outbuf,datasize); | 195 | write(fd_dec,outbuf,datasize); |
192 | } | 196 | } |
diff --git a/apps/codecs/libcook/rm.c b/apps/codecs/libcook/rm.c index 92b6428462..b2ccfc2480 100644 --- a/apps/codecs/libcook/rm.c +++ b/apps/codecs/libcook/rm.c | |||
@@ -38,6 +38,21 @@ | |||
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | /* Some Rockbox-like functions (these should be implemented in metadata_common.[ch] */ | 40 | /* Some Rockbox-like functions (these should be implemented in metadata_common.[ch] */ |
41 | static uint8_t get_uint8(uint8_t *buf) | ||
42 | { | ||
43 | return (uint8_t)buf[0]; | ||
44 | } | ||
45 | |||
46 | static uint16_t get_uint16be(uint8_t *buf) | ||
47 | { | ||
48 | return (uint16_t)((buf[0] << 8)|buf[1]); | ||
49 | } | ||
50 | |||
51 | static uint32_t get_uint32be(uint8_t *buf) | ||
52 | { | ||
53 | return (uint32_t)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); | ||
54 | } | ||
55 | |||
41 | static int read_uint8(int fd, uint8_t* buf) | 56 | static int read_uint8(int fd, uint8_t* buf) |
42 | { | 57 | { |
43 | unsigned char tmp[1]; | 58 | unsigned char tmp[1]; |
@@ -79,6 +94,11 @@ off_t filesize(int fd) | |||
79 | } | 94 | } |
80 | } | 95 | } |
81 | 96 | ||
97 | void advance_buffer(uint8_t **buf, int val) | ||
98 | { | ||
99 | *buf += val; | ||
100 | } | ||
101 | |||
82 | int read_cook_extradata(int fd, RMContext *rmctx) { | 102 | int read_cook_extradata(int fd, RMContext *rmctx) { |
83 | read_uint32be(fd, &rmctx->cook_version); | 103 | read_uint32be(fd, &rmctx->cook_version); |
84 | read_uint16be(fd, &rmctx->samples_pf_pc); | 104 | read_uint16be(fd, &rmctx->samples_pf_pc); |
@@ -273,7 +293,6 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
273 | uint32_t duration; | 293 | uint32_t duration; |
274 | uint32_t preroll; | 294 | uint32_t preroll; |
275 | uint32_t index_offset; | 295 | uint32_t index_offset; |
276 | uint32_t data_offset; | ||
277 | uint16_t num_streams; | 296 | uint16_t num_streams; |
278 | uint16_t flags = 0; | 297 | uint16_t flags = 0; |
279 | 298 | ||
@@ -331,7 +350,7 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
331 | read_uint32be(fd, &duration); | 350 | read_uint32be(fd, &duration); |
332 | read_uint32be(fd, &preroll); | 351 | read_uint32be(fd, &preroll); |
333 | read_uint32be(fd, &index_offset); | 352 | read_uint32be(fd, &index_offset); |
334 | read_uint32be(fd, &data_offset); | 353 | read_uint32be(fd, &rmctx->data_offset); |
335 | read_uint16be(fd, &num_streams); | 354 | read_uint16be(fd, &num_streams); |
336 | read_uint16be(fd, &rmctx->flags); | 355 | read_uint16be(fd, &rmctx->flags); |
337 | skipped += 40; | 356 | skipped += 40; |
@@ -344,7 +363,7 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
344 | printf(" duration = %d\n",duration); | 363 | printf(" duration = %d\n",duration); |
345 | printf(" preroll = %d\n",preroll); | 364 | printf(" preroll = %d\n",preroll); |
346 | printf(" index_offset = %d\n",index_offset); | 365 | printf(" index_offset = %d\n",index_offset); |
347 | printf(" data_offset = %d\n",data_offset); | 366 | printf(" data_offset = %d\n",rmctx->data_offset); |
348 | printf(" num_streams = %d\n",num_streams); | 367 | printf(" num_streams = %d\n",num_streams); |
349 | printf(" flags=0x%04x\n",flags); | 368 | printf(" flags=0x%04x\n",flags); |
350 | break; | 369 | break; |
@@ -474,6 +493,54 @@ void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt) | |||
474 | 493 | ||
475 | //return pkt->data; | 494 | //return pkt->data; |
476 | } | 495 | } |
496 | |||
497 | /** | ||
498 | * Another version of rm_get_packet which reads from a memory buffer | ||
499 | * instead of readind from a file descriptor. | ||
500 | **/ | ||
501 | void rm_get_packet_membuf(uint8_t **filebuf,RMContext *rmctx, RMPacket *pkt) | ||
502 | { | ||
503 | uint8_t unknown; | ||
504 | uint16_t x, place; | ||
505 | uint16_t sps = rmctx->sub_packet_size; | ||
506 | uint16_t h = rmctx->sub_packet_h; | ||
507 | uint16_t y = rmctx->sub_packet_cnt; | ||
508 | uint16_t w = rmctx->audio_framesize; | ||
509 | do | ||
510 | { | ||
511 | y = rmctx->sub_packet_cnt; | ||
512 | pkt->version = get_uint16be(*filebuf); | ||
513 | pkt->length = get_uint16be(*filebuf+2); | ||
514 | pkt->stream_number = get_uint16be(*filebuf+4); | ||
515 | pkt->timestamp = get_uint32be(*filebuf+6); | ||
516 | DEBUGF(" version = %d\n" | ||
517 | " length = %d\n" | ||
518 | " stream = %d\n" | ||
519 | " timestamp= %d\n",pkt->version,pkt->length,pkt->stream_number,pkt->timestamp); | ||
520 | |||
521 | unknown = get_uint8(*filebuf+10); | ||
522 | pkt->flags = get_uint8(*filebuf+11); | ||
523 | |||
524 | if(pkt->version == 1) | ||
525 | unknown = get_uint8(*filebuf+10); | ||
526 | |||
527 | if (pkt->flags & 2) /* keyframe */ | ||
528 | y = rmctx->sub_packet_cnt = 0; | ||
529 | if (!y) /* if keyframe update playback elapsed time */ | ||
530 | rmctx->audiotimestamp = pkt->timestamp; | ||
531 | |||
532 | advance_buffer(filebuf,12); | ||
533 | |||
534 | for(x = 0 ; x < w/sps; x++) | ||
535 | { | ||
536 | place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1)); | ||
537 | pkt->frames[place/sps] = *filebuf; | ||
538 | advance_buffer(filebuf,sps); | ||
539 | } | ||
540 | rmctx->audio_pkt_cnt++; | ||
541 | }while(++(rmctx->sub_packet_cnt) < h); | ||
542 | } | ||
543 | |||
477 | #ifdef DEBUG | 544 | #ifdef DEBUG |
478 | void dump_rm_context(RMContext *rmctx) | 545 | void dump_rm_context(RMContext *rmctx) |
479 | { | 546 | { |
diff --git a/apps/codecs/libcook/rm.h b/apps/codecs/libcook/rm.h index 8e2ebe8a16..bdd03f3db2 100644 --- a/apps/codecs/libcook/rm.h +++ b/apps/codecs/libcook/rm.h | |||
@@ -27,6 +27,7 @@ | |||
27 | typedef struct rm_packet | 27 | typedef struct rm_packet |
28 | { | 28 | { |
29 | uint8_t data[30000]; /* Reordered data. No malloc, hence the size */ | 29 | uint8_t data[30000]; /* Reordered data. No malloc, hence the size */ |
30 | uint8_t *frames[100]; /* Pointers to ordered audio frames in buffer */ | ||
30 | uint16_t version; | 31 | uint16_t version; |
31 | uint16_t length; | 32 | uint16_t length; |
32 | uint32_t timestamp; | 33 | uint32_t timestamp; |
@@ -44,6 +45,7 @@ typedef struct rm_context | |||
44 | int audio_pkt_cnt; /* Output packet counter*/ | 45 | int audio_pkt_cnt; /* Output packet counter*/ |
45 | 46 | ||
46 | /* Stream Variables */ | 47 | /* Stream Variables */ |
48 | uint32_t data_offset; | ||
47 | uint32_t audiotimestamp; /* Audio packet timestamp*/ | 49 | uint32_t audiotimestamp; /* Audio packet timestamp*/ |
48 | uint16_t sub_packet_cnt; /* Subpacket counter, used while reading */ | 50 | uint16_t sub_packet_cnt; /* Subpacket counter, used while reading */ |
49 | uint16_t sub_packet_size, sub_packet_h, coded_framesize; /* Descrambling parameters from container */ | 51 | uint16_t sub_packet_size, sub_packet_h, coded_framesize; /* Descrambling parameters from container */ |
@@ -75,4 +77,7 @@ int open_wav(char* filename); | |||
75 | void close_wav(int fd, RMContext *rmctx); | 77 | void close_wav(int fd, RMContext *rmctx); |
76 | int real_parse_header(int fd, RMContext *rmctx); | 78 | int real_parse_header(int fd, RMContext *rmctx); |
77 | void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt); | 79 | void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt); |
80 | void rm_get_packet_membuf(uint8_t **filebuf,RMContext *rmctx, RMPacket *pkt); | ||
81 | off_t filesize(int fd); | ||
82 | void advance_buffer(uint8_t **buf, int val); | ||
78 | #endif | 83 | #endif |