summaryrefslogtreecommitdiff
path: root/apps/codecs/libatrac
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libatrac')
-rw-r--r--apps/codecs/libatrac/Makefile.test2
-rw-r--r--apps/codecs/libatrac/atrac3.c246
-rw-r--r--apps/codecs/libatrac/atrac3.h80
-rw-r--r--apps/codecs/libatrac/main.c167
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 @@
1CFLAGS = -Wall -O3 -DTEST -D"DEBUGF=printf" -D"ROCKBOX_LITTLE_ENDIAN=1" -D"ICONST_ATTR=" -D"ICODE_ATTR=" 1CFLAGS = -Wall -O3 -DTEST -D"DEBUGF=printf" -D"ROCKBOX_LITTLE_ENDIAN=1" -D"ICONST_ATTR=" -D"ICODE_ATTR="
2OBJS = atrac3.o bitstream.o ../librm/rm.o fixp_math.o ../lib/mdct2.o ../lib/mdct_lookup.o 2OBJS = atrac3.o bitstream.o ../librm/rm.o fixp_math.o ../lib/mdct2.o ../lib/mdct_lookup.o main.o
3 3
4atractest: $(OBJS) 4atractest: $(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. */
62typedef struct {
63 int num_gain_data;
64 int levcode[8];
65 int loccode[8];
66} gain_info;
67
68typedef struct {
69 gain_info gBlock[4];
70} gain_block;
71
72typedef struct {
73 int pos;
74 int numCoefs;
75 int32_t coef[8];
76} tonal_component;
77
78typedef 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
94typedef 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
132static int32_t qmf_window[48]; 51static int32_t qmf_window[48];
133static VLC spectral_coeff_tab[7]; 52static VLC spectral_coeff_tab[7];
134static channel_unit channel_units[2]; 53static 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
862static int atrac3_decode_frame(RMContext *rmctx, ATRAC3Context *q, 781int 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
911static av_cold int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx) 830int 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 ***************************************************************/
1038static 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
1054int 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
1065void 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
1118int 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. */
5typedef struct {
6 int num_gain_data;
7 int levcode[8];
8 int loccode[8];
9} gain_info;
10
11typedef struct {
12 gain_info gBlock[4];
13} gain_block;
14
15typedef struct {
16 int pos;
17 int numCoefs;
18 int32_t coef[8];
19} tonal_component;
20
21typedef 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
37typedef 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
75int atrac3_decode_init(ATRAC3Context *q, RMContext *rmctx);
76
77int 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
12static 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
28int 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
39void 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
92int 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}