diff options
Diffstat (limited to 'apps/codecs/libatrac/main.c')
-rw-r--r-- | apps/codecs/libatrac/main.c | 167 |
1 files changed, 167 insertions, 0 deletions
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 | } | ||