diff options
Diffstat (limited to 'apps/codecs/libatrac')
-rw-r--r-- | apps/codecs/libatrac/Makefile.test | 2 | ||||
-rw-r--r-- | apps/codecs/libatrac/atrac3.c | 246 | ||||
-rw-r--r-- | apps/codecs/libatrac/atrac3.h | 80 | ||||
-rw-r--r-- | apps/codecs/libatrac/main.c | 167 |
4 files changed, 251 insertions, 244 deletions
diff --git a/apps/codecs/libatrac/Makefile.test b/apps/codecs/libatrac/Makefile.test index 13809d1feb..f9a1c2f0e6 100644 --- a/apps/codecs/libatrac/Makefile.test +++ b/apps/codecs/libatrac/Makefile.test | |||
@@ -1,5 +1,5 @@ | |||
1 | CFLAGS = -Wall -O3 -DTEST -D"DEBUGF=printf" -D"ROCKBOX_LITTLE_ENDIAN=1" -D"ICONST_ATTR=" -D"ICODE_ATTR=" | 1 | CFLAGS = -Wall -O3 -DTEST -D"DEBUGF=printf" -D"ROCKBOX_LITTLE_ENDIAN=1" -D"ICONST_ATTR=" -D"ICODE_ATTR=" |
2 | OBJS = atrac3.o bitstream.o ../librm/rm.o fixp_math.o ../lib/mdct2.o ../lib/mdct_lookup.o | 2 | OBJS = atrac3.o bitstream.o ../librm/rm.o fixp_math.o ../lib/mdct2.o ../lib/mdct_lookup.o main.o |
3 | 3 | ||
4 | atractest: $(OBJS) | 4 | atractest: $(OBJS) |
5 | gcc -o atractest $(OBJS) | 5 | gcc -o atractest $(OBJS) |
diff --git a/apps/codecs/libatrac/atrac3.c b/apps/codecs/libatrac/atrac3.c index f7181f7e6b..26bffd42d4 100644 --- a/apps/codecs/libatrac/atrac3.c +++ b/apps/codecs/libatrac/atrac3.c | |||
@@ -36,21 +36,11 @@ | |||
36 | #include <stddef.h> | 36 | #include <stddef.h> |
37 | #include <stdio.h> | 37 | #include <stdio.h> |
38 | 38 | ||
39 | #include "bitstream.h" | ||
40 | #include "bytestream.h" | 39 | #include "bytestream.h" |
41 | 40 | #include "atrac3.h" | |
42 | #include <stdint.h> | ||
43 | #include <sys/types.h> | ||
44 | #include <sys/stat.h> | ||
45 | #include <fcntl.h> | ||
46 | #include <unistd.h> | ||
47 | #include <string.h> | ||
48 | |||
49 | #include "../librm/rm.h" | ||
50 | #include "atrac3data.h" | 41 | #include "atrac3data.h" |
51 | #include "atrac3data_fixed.h" | 42 | #include "atrac3data_fixed.h" |
52 | #include "fixp_math.h" | 43 | #include "fixp_math.h" |
53 | //#include "fixp_mdct.h" | ||
54 | #include "../lib/mdct2.h" | 44 | #include "../lib/mdct2.h" |
55 | 45 | ||
56 | #define JOINT_STEREO 0x12 | 46 | #define JOINT_STEREO 0x12 |
@@ -58,77 +48,6 @@ | |||
58 | 48 | ||
59 | #define AVERROR(...) -1 | 49 | #define AVERROR(...) -1 |
60 | 50 | ||
61 | /* These structures are needed to store the parsed gain control data. */ | ||
62 | typedef struct { | ||
63 | int num_gain_data; | ||
64 | int levcode[8]; | ||
65 | int loccode[8]; | ||
66 | } gain_info; | ||
67 | |||
68 | typedef struct { | ||
69 | gain_info gBlock[4]; | ||
70 | } gain_block; | ||
71 | |||
72 | typedef struct { | ||
73 | int pos; | ||
74 | int numCoefs; | ||
75 | int32_t coef[8]; | ||
76 | } tonal_component; | ||
77 | |||
78 | typedef struct { | ||
79 | int bandsCoded; | ||
80 | int numComponents; | ||
81 | tonal_component components[64]; | ||
82 | int32_t prevFrame[1024]; | ||
83 | int gcBlkSwitch; | ||
84 | gain_block gainBlock[2]; | ||
85 | |||
86 | int32_t spectrum[1024] __attribute__((aligned(16))); | ||
87 | int32_t IMDCT_buf[1024] __attribute__((aligned(16))); | ||
88 | |||
89 | int32_t delayBuf1[46]; ///<qmf delay buffers | ||
90 | int32_t delayBuf2[46]; | ||
91 | int32_t delayBuf3[46]; | ||
92 | } channel_unit; | ||
93 | |||
94 | typedef struct { | ||
95 | GetBitContext gb; | ||
96 | //@{ | ||
97 | /** stream data */ | ||
98 | int channels; | ||
99 | int codingMode; | ||
100 | int bit_rate; | ||
101 | int sample_rate; | ||
102 | int samples_per_channel; | ||
103 | int samples_per_frame; | ||
104 | |||
105 | int bits_per_frame; | ||
106 | int bytes_per_frame; | ||
107 | int pBs; | ||
108 | channel_unit* pUnits; | ||
109 | //@} | ||
110 | //@{ | ||
111 | /** joint-stereo related variables */ | ||
112 | int matrix_coeff_index_prev[4]; | ||
113 | int matrix_coeff_index_now[4]; | ||
114 | int matrix_coeff_index_next[4]; | ||
115 | int weighting_delay[6]; | ||
116 | //@} | ||
117 | //@{ | ||
118 | /** data buffers */ | ||
119 | int32_t outSamples[2048]; | ||
120 | uint8_t decoded_bytes_buffer[1024]; | ||
121 | int32_t tempBuf[1070]; | ||
122 | //@} | ||
123 | //@{ | ||
124 | /** extradata */ | ||
125 | int atrac3version; | ||
126 | int delay; | ||
127 | int scrambled_stream; | ||
128 | int frame_factor; | ||
129 | //@} | ||
130 | } ATRAC3Context; | ||
131 | |||
132 | static int32_t qmf_window[48]; | 51 | static int32_t qmf_window[48]; |
133 | static VLC spectral_coeff_tab[7]; | 52 | static VLC spectral_coeff_tab[7]; |
134 | static channel_unit channel_units[2]; | 53 | static channel_unit channel_units[2]; |
@@ -859,7 +778,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) | |||
859 | * @param rmctx pointer to the AVCodecContext | 778 | * @param rmctx pointer to the AVCodecContext |
860 | */ | 779 | */ |
861 | 780 | ||
862 | static int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q, | 781 | int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q, |
863 | void *data, int *data_size, | 782 | void *data, int *data_size, |
864 | const uint8_t *buf, int buf_size) { | 783 | const uint8_t *buf, int buf_size) { |
865 | int result = 0, i; | 784 | int result = 0, i; |
@@ -908,7 +827,7 @@ static int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q, | |||
908 | * @param rmctx pointer to the RMContext | 827 | * @param rmctx pointer to the RMContext |
909 | */ | 828 | */ |
910 | 829 | ||
911 | static av_cold int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx) | 830 | int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx) |
912 | { | 831 | { |
913 | int i; | 832 | int i; |
914 | const uint8_t *edata_ptr = rmctx->codec_extradata; | 833 | const uint8_t *edata_ptr = rmctx->codec_extradata; |
@@ -1032,162 +951,3 @@ static av_cold int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx) | |||
1032 | return 0; | 951 | return 0; |
1033 | } | 952 | } |
1034 | 953 | ||
1035 | /*************************************************************** | ||
1036 | * Following is a test program to convert from atrac/rm to wav * | ||
1037 | ***************************************************************/ | ||
1038 | static unsigned char wav_header[44]={ | ||
1039 | 'R','I','F','F',// 0 - ChunkID | ||
1040 | 0,0,0,0, // 4 - ChunkSize (filesize-8) | ||
1041 | 'W','A','V','E',// 8 - Format | ||
1042 | 'f','m','t',' ',// 12 - SubChunkID | ||
1043 | 16,0,0,0, // 16 - SubChunk1ID // 16 for PCM | ||
1044 | 1,0, // 20 - AudioFormat (1=Uncompressed) | ||
1045 | 2,0, // 22 - NumChannels | ||
1046 | 0,0,0,0, // 24 - SampleRate in Hz | ||
1047 | 0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8) | ||
1048 | 4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8) | ||
1049 | 16,0, // 34 - BitsPerSample | ||
1050 | 'd','a','t','a',// 36 - Subchunk2ID | ||
1051 | 0,0,0,0 // 40 - Subchunk2Size | ||
1052 | }; | ||
1053 | |||
1054 | int open_wav(char* filename) { | ||
1055 | int fd,res; | ||
1056 | |||
1057 | fd=open(filename,O_CREAT|O_WRONLY|O_TRUNC,S_IRUSR|S_IWUSR); | ||
1058 | if (fd >= 0) { | ||
1059 | res = write(fd,wav_header,sizeof(wav_header)); | ||
1060 | } | ||
1061 | |||
1062 | return(fd); | ||
1063 | } | ||
1064 | |||
1065 | void close_wav(int fd, RMContext *rmctx, ATRAC3Context *q) { | ||
1066 | int x,res; | ||
1067 | int filesize; | ||
1068 | int bytes_per_sample = 2; | ||
1069 | int samples_per_frame = q->samples_per_frame; | ||
1070 | int nb_channels = rmctx->nb_channels; | ||
1071 | int sample_rate = rmctx->sample_rate; | ||
1072 | int nb_frames = rmctx->audio_framesize/rmctx->block_align * rmctx->nb_packets - 2; // first 2 frames have no valid audio; skipped in output | ||
1073 | |||
1074 | filesize= samples_per_frame*bytes_per_sample*nb_frames +44; | ||
1075 | printf("Filesize = %d\n",filesize); | ||
1076 | |||
1077 | // ChunkSize | ||
1078 | x=filesize-8; | ||
1079 | wav_header[4]=(x&0xff); | ||
1080 | wav_header[5]=(x&0xff00)>>8; | ||
1081 | wav_header[6]=(x&0xff0000)>>16; | ||
1082 | wav_header[7]=(x&0xff000000)>>24; | ||
1083 | |||
1084 | // Number of channels | ||
1085 | wav_header[22]=nb_channels; | ||
1086 | |||
1087 | // Samplerate | ||
1088 | wav_header[24]=sample_rate&0xff; | ||
1089 | wav_header[25]=(sample_rate&0xff00)>>8; | ||
1090 | wav_header[26]=(sample_rate&0xff0000)>>16; | ||
1091 | wav_header[27]=(sample_rate&0xff000000)>>24; | ||
1092 | |||
1093 | // ByteRate | ||
1094 | x=sample_rate*bytes_per_sample*nb_channels; | ||
1095 | wav_header[28]=(x&0xff); | ||
1096 | wav_header[29]=(x&0xff00)>>8; | ||
1097 | wav_header[30]=(x&0xff0000)>>16; | ||
1098 | wav_header[31]=(x&0xff000000)>>24; | ||
1099 | |||
1100 | // BlockAlign | ||
1101 | wav_header[32]=rmctx->block_align;//2*rmctx->nb_channels; | ||
1102 | |||
1103 | // Bits per sample | ||
1104 | wav_header[34]=16; | ||
1105 | |||
1106 | // Subchunk2Size | ||
1107 | x=filesize-44; | ||
1108 | wav_header[40]=(x&0xff); | ||
1109 | wav_header[41]=(x&0xff00)>>8; | ||
1110 | wav_header[42]=(x&0xff0000)>>16; | ||
1111 | wav_header[43]=(x&0xff000000)>>24; | ||
1112 | |||
1113 | lseek(fd,0,SEEK_SET); | ||
1114 | res = write(fd,wav_header,sizeof(wav_header)); | ||
1115 | close(fd); | ||
1116 | } | ||
1117 | |||
1118 | int main(int argc, char *argv[]) | ||
1119 | { | ||
1120 | int fd, fd_dec; | ||
1121 | int res, i, datasize = 0; | ||
1122 | |||
1123 | #ifdef DUMP_RAW_FRAMES | ||
1124 | char filename[15]; | ||
1125 | int fd_out; | ||
1126 | #endif | ||
1127 | int16_t outbuf[2048]; | ||
1128 | uint16_t fs,sps,h; | ||
1129 | uint32_t packet_count; | ||
1130 | ATRAC3Context q; | ||
1131 | RMContext rmctx; | ||
1132 | RMPacket pkt; | ||
1133 | |||
1134 | memset(&q,0,sizeof(ATRAC3Context)); | ||
1135 | memset(&rmctx,0,sizeof(RMContext)); | ||
1136 | memset(&pkt,0,sizeof(RMPacket)); | ||
1137 | |||
1138 | if (argc != 2) { | ||
1139 | DEBUGF("Incorrect number of arguments\n"); | ||
1140 | return -1; | ||
1141 | } | ||
1142 | |||
1143 | fd = open(argv[1],O_RDONLY); | ||
1144 | if (fd < 0) { | ||
1145 | DEBUGF("Error opening file %s\n", argv[1]); | ||
1146 | return -1; | ||
1147 | } | ||
1148 | |||
1149 | /* copy the input rm file to a memory buffer */ | ||
1150 | uint8_t * filebuf = (uint8_t *)calloc((int)filesize(fd),sizeof(uint8_t)); | ||
1151 | res = read(fd,filebuf,filesize(fd)); | ||
1152 | |||
1153 | fd_dec = open_wav("output.wav"); | ||
1154 | if (fd_dec < 0) { | ||
1155 | DEBUGF("Error creating output file\n"); | ||
1156 | return -1; | ||
1157 | } | ||
1158 | res = real_parse_header(fd, &rmctx); | ||
1159 | packet_count = rmctx.nb_packets; | ||
1160 | rmctx.audio_framesize = rmctx.block_align; | ||
1161 | rmctx.block_align = rmctx.sub_packet_size; | ||
1162 | fs = rmctx.audio_framesize; | ||
1163 | sps= rmctx.block_align; | ||
1164 | h = rmctx.sub_packet_h; | ||
1165 | atrac3_decode_init(&q,&rmctx); | ||
1166 | |||
1167 | /* change the buffer pointer to point at the first audio frame */ | ||
1168 | advance_buffer(&filebuf, rmctx.data_offset + DATA_HEADER_SIZE); | ||
1169 | while(packet_count) | ||
1170 | { | ||
1171 | rm_get_packet(&filebuf, &rmctx, &pkt); | ||
1172 | for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) | ||
1173 | { | ||
1174 | /* output raw audio frames that are sent to the decoder into separate files */ | ||
1175 | #ifdef DUMP_RAW_FRAMES | ||
1176 | snprintf(filename,sizeof(filename),"dump%d.raw",++x); | ||
1177 | fd_out = open(filename,O_WRONLY|O_CREAT|O_APPEND); | ||
1178 | write(fd_out,pkt.frames[i],sps); | ||
1179 | close(fd_out); | ||
1180 | #endif | ||
1181 | if(pkt.length > 0) | ||
1182 | res = atrac3_decode_frame(&rmctx,&q, outbuf, &datasize, pkt.frames[i] , rmctx.block_align); | ||
1183 | rmctx.frame_number++; | ||
1184 | res = write(fd_dec,outbuf,datasize); | ||
1185 | } | ||
1186 | packet_count -= rmctx.audio_pkt_cnt; | ||
1187 | rmctx.audio_pkt_cnt = 0; | ||
1188 | } | ||
1189 | close_wav(fd_dec, &rmctx, &q); | ||
1190 | close(fd); | ||
1191 | |||
1192 | return 0; | ||
1193 | } | ||
diff --git a/apps/codecs/libatrac/atrac3.h b/apps/codecs/libatrac/atrac3.h new file mode 100644 index 0000000000..e4121d7b4e --- /dev/null +++ b/apps/codecs/libatrac/atrac3.h | |||
@@ -0,0 +1,80 @@ | |||
1 | #include "bitstream.h" | ||
2 | #include "../librm/rm.h" | ||
3 | |||
4 | /* These structures are needed to store the parsed gain control data. */ | ||
5 | typedef struct { | ||
6 | int num_gain_data; | ||
7 | int levcode[8]; | ||
8 | int loccode[8]; | ||
9 | } gain_info; | ||
10 | |||
11 | typedef struct { | ||
12 | gain_info gBlock[4]; | ||
13 | } gain_block; | ||
14 | |||
15 | typedef struct { | ||
16 | int pos; | ||
17 | int numCoefs; | ||
18 | int32_t coef[8]; | ||
19 | } tonal_component; | ||
20 | |||
21 | typedef struct { | ||
22 | int bandsCoded; | ||
23 | int numComponents; | ||
24 | tonal_component components[64]; | ||
25 | int32_t prevFrame[1024]; | ||
26 | int gcBlkSwitch; | ||
27 | gain_block gainBlock[2]; | ||
28 | |||
29 | int32_t spectrum[1024] __attribute__((aligned(16))); | ||
30 | int32_t IMDCT_buf[1024] __attribute__((aligned(16))); | ||
31 | |||
32 | int32_t delayBuf1[46]; ///<qmf delay buffers | ||
33 | int32_t delayBuf2[46]; | ||
34 | int32_t delayBuf3[46]; | ||
35 | } channel_unit; | ||
36 | |||
37 | typedef struct { | ||
38 | GetBitContext gb; | ||
39 | //@{ | ||
40 | /** stream data */ | ||
41 | int channels; | ||
42 | int codingMode; | ||
43 | int bit_rate; | ||
44 | int sample_rate; | ||
45 | int samples_per_channel; | ||
46 | int samples_per_frame; | ||
47 | |||
48 | int bits_per_frame; | ||
49 | int bytes_per_frame; | ||
50 | int pBs; | ||
51 | channel_unit* pUnits; | ||
52 | //@} | ||
53 | //@{ | ||
54 | /** joint-stereo related variables */ | ||
55 | int matrix_coeff_index_prev[4]; | ||
56 | int matrix_coeff_index_now[4]; | ||
57 | int matrix_coeff_index_next[4]; | ||
58 | int weighting_delay[6]; | ||
59 | //@} | ||
60 | //@{ | ||
61 | /** data buffers */ | ||
62 | int32_t outSamples[2048]; | ||
63 | uint8_t decoded_bytes_buffer[1024]; | ||
64 | int32_t tempBuf[1070]; | ||
65 | //@} | ||
66 | //@{ | ||
67 | /** extradata */ | ||
68 | int atrac3version; | ||
69 | int delay; | ||
70 | int scrambled_stream; | ||
71 | int frame_factor; | ||
72 | //@} | ||
73 | } ATRAC3Context; | ||
74 | |||
75 | int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx); | ||
76 | |||
77 | int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q, | ||
78 | void *data, int *data_size, | ||
79 | const uint8_t *buf, int buf_size); | ||
80 | |||
diff --git a/apps/codecs/libatrac/main.c b/apps/codecs/libatrac/main.c new file mode 100644 index 0000000000..826dacf819 --- /dev/null +++ b/apps/codecs/libatrac/main.c | |||
@@ -0,0 +1,167 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdint.h> | ||
3 | #include <sys/types.h> | ||
4 | #include <sys/stat.h> | ||
5 | #include <fcntl.h> | ||
6 | #include <unistd.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #include "atrac3.h" | ||
10 | #include "../librm/rm.h" | ||
11 | |||
12 | static unsigned char wav_header[44]={ | ||
13 | 'R','I','F','F',// 0 - ChunkID | ||
14 | 0,0,0,0, // 4 - ChunkSize (filesize-8) | ||
15 | 'W','A','V','E',// 8 - Format | ||
16 | 'f','m','t',' ',// 12 - SubChunkID | ||
17 | 16,0,0,0, // 16 - SubChunk1ID // 16 for PCM | ||
18 | 1,0, // 20 - AudioFormat (1=Uncompressed) | ||
19 | 2,0, // 22 - NumChannels | ||
20 | 0,0,0,0, // 24 - SampleRate in Hz | ||
21 | 0,0,0,0, // 28 - Byte Rate (SampleRate*NumChannels*(BitsPerSample/8) | ||
22 | 4,0, // 32 - BlockAlign (== NumChannels * BitsPerSample/8) | ||
23 | 16,0, // 34 - BitsPerSample | ||
24 | 'd','a','t','a',// 36 - Subchunk2ID | ||
25 | 0,0,0,0 // 40 - Subchunk2Size | ||
26 | }; | ||
27 | |||
28 | int open_wav(char* filename) { | ||
29 | int fd,res; | ||
30 | |||
31 | fd=open(filename,O_CREAT|O_WRONLY|O_TRUNC,S_IRUSR|S_IWUSR); | ||
32 | if (fd >= 0) { | ||
33 | res = write(fd,wav_header,sizeof(wav_header)); | ||
34 | } | ||
35 | |||
36 | return(fd); | ||
37 | } | ||
38 | |||
39 | void close_wav(int fd, RMContext *rmctx, ATRAC3Context *q) { | ||
40 | int x,res; | ||
41 | int filesize; | ||
42 | int bytes_per_sample = 2; | ||
43 | int samples_per_frame = q->samples_per_frame; | ||
44 | int nb_channels = rmctx->nb_channels; | ||
45 | int sample_rate = rmctx->sample_rate; | ||
46 | int nb_frames = rmctx->audio_framesize/rmctx->block_align * rmctx->nb_packets - 2; // first 2 frames have no valid audio; skipped in output | ||
47 | |||
48 | filesize= samples_per_frame*bytes_per_sample*nb_frames +44; | ||
49 | printf("Filesize = %d\n",filesize); | ||
50 | |||
51 | // ChunkSize | ||
52 | x=filesize-8; | ||
53 | wav_header[4]=(x&0xff); | ||
54 | wav_header[5]=(x&0xff00)>>8; | ||
55 | wav_header[6]=(x&0xff0000)>>16; | ||
56 | wav_header[7]=(x&0xff000000)>>24; | ||
57 | |||
58 | // Number of channels | ||
59 | wav_header[22]=nb_channels; | ||
60 | |||
61 | // Samplerate | ||
62 | wav_header[24]=sample_rate&0xff; | ||
63 | wav_header[25]=(sample_rate&0xff00)>>8; | ||
64 | wav_header[26]=(sample_rate&0xff0000)>>16; | ||
65 | wav_header[27]=(sample_rate&0xff000000)>>24; | ||
66 | |||
67 | // ByteRate | ||
68 | x=sample_rate*bytes_per_sample*nb_channels; | ||
69 | wav_header[28]=(x&0xff); | ||
70 | wav_header[29]=(x&0xff00)>>8; | ||
71 | wav_header[30]=(x&0xff0000)>>16; | ||
72 | wav_header[31]=(x&0xff000000)>>24; | ||
73 | |||
74 | // BlockAlign | ||
75 | wav_header[32]=rmctx->block_align;//2*rmctx->nb_channels; | ||
76 | |||
77 | // Bits per sample | ||
78 | wav_header[34]=16; | ||
79 | |||
80 | // Subchunk2Size | ||
81 | x=filesize-44; | ||
82 | wav_header[40]=(x&0xff); | ||
83 | wav_header[41]=(x&0xff00)>>8; | ||
84 | wav_header[42]=(x&0xff0000)>>16; | ||
85 | wav_header[43]=(x&0xff000000)>>24; | ||
86 | |||
87 | lseek(fd,0,SEEK_SET); | ||
88 | res = write(fd,wav_header,sizeof(wav_header)); | ||
89 | close(fd); | ||
90 | } | ||
91 | |||
92 | int main(int argc, char *argv[]) | ||
93 | { | ||
94 | int fd, fd_dec; | ||
95 | int res, i, datasize = 0; | ||
96 | |||
97 | #ifdef DUMP_RAW_FRAMES | ||
98 | char filename[15]; | ||
99 | int fd_out; | ||
100 | #endif | ||
101 | int16_t outbuf[2048]; | ||
102 | uint16_t fs,sps,h; | ||
103 | uint32_t packet_count; | ||
104 | ATRAC3Context q; | ||
105 | RMContext rmctx; | ||
106 | RMPacket pkt; | ||
107 | |||
108 | memset(&q,0,sizeof(ATRAC3Context)); | ||
109 | memset(&rmctx,0,sizeof(RMContext)); | ||
110 | memset(&pkt,0,sizeof(RMPacket)); | ||
111 | |||
112 | if (argc != 2) { | ||
113 | DEBUGF("Incorrect number of arguments\n"); | ||
114 | return -1; | ||
115 | } | ||
116 | |||
117 | fd = open(argv[1],O_RDONLY); | ||
118 | if (fd < 0) { | ||
119 | DEBUGF("Error opening file %s\n", argv[1]); | ||
120 | return -1; | ||
121 | } | ||
122 | |||
123 | /* copy the input rm file to a memory buffer */ | ||
124 | uint8_t * filebuf = (uint8_t *)calloc((int)filesize(fd),sizeof(uint8_t)); | ||
125 | res = read(fd,filebuf,filesize(fd)); | ||
126 | |||
127 | fd_dec = open_wav("output.wav"); | ||
128 | if (fd_dec < 0) { | ||
129 | DEBUGF("Error creating output file\n"); | ||
130 | return -1; | ||
131 | } | ||
132 | res = real_parse_header(fd, &rmctx); | ||
133 | packet_count = rmctx.nb_packets; | ||
134 | rmctx.audio_framesize = rmctx.block_align; | ||
135 | rmctx.block_align = rmctx.sub_packet_size; | ||
136 | fs = rmctx.audio_framesize; | ||
137 | sps= rmctx.block_align; | ||
138 | h = rmctx.sub_packet_h; | ||
139 | atrac3_decode_init(&q,&rmctx); | ||
140 | |||
141 | /* change the buffer pointer to point at the first audio frame */ | ||
142 | advance_buffer(&filebuf, rmctx.data_offset + DATA_HEADER_SIZE); | ||
143 | while(packet_count) | ||
144 | { | ||
145 | rm_get_packet(&filebuf, &rmctx, &pkt); | ||
146 | for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) | ||
147 | { | ||
148 | /* output raw audio frames that are sent to the decoder into separate files */ | ||
149 | #ifdef DUMP_RAW_FRAMES | ||
150 | snprintf(filename,sizeof(filename),"dump%d.raw",++x); | ||
151 | fd_out = open(filename,O_WRONLY|O_CREAT|O_APPEND); | ||
152 | write(fd_out,pkt.frames[i],sps); | ||
153 | close(fd_out); | ||
154 | #endif | ||
155 | if(pkt.length > 0) | ||
156 | res = atrac3_decode_frame(&rmctx,&q, outbuf, &datasize, pkt.frames[i] , rmctx.block_align); | ||
157 | rmctx.frame_number++; | ||
158 | res = write(fd_dec,outbuf,datasize); | ||
159 | } | ||
160 | packet_count -= rmctx.audio_pkt_cnt; | ||
161 | rmctx.audio_pkt_cnt = 0; | ||
162 | } | ||
163 | close_wav(fd_dec, &rmctx, &q); | ||
164 | close(fd); | ||
165 | |||
166 | return 0; | ||
167 | } | ||