annotate music2/wavfile.cc @ 60:e16e13d8cd68

Replaced SATURATE -> ADD, implemented objComposite, corrected minor things
author Thibaut GIRKA <thib@sitedethib.com>
date Fri, 18 Dec 2009 20:41:38 +0100
parents 15a18fbe6f21
children 4416cfac86ae
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
223b71206888 Initial import
thib
parents:
diff changeset
1 /*
223b71206888 Initial import
thib
parents:
diff changeset
2 * wavfile.c WAV file check
223b71206888 Initial import
thib
parents:
diff changeset
3 *
223b71206888 Initial import
thib
parents:
diff changeset
4 * Copyright: wavfile.c (c) Erik de Castro Lopo erikd@zip.com.au
223b71206888 Initial import
thib
parents:
diff changeset
5 *
223b71206888 Initial import
thib
parents:
diff changeset
6 * Modified : 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
223b71206888 Initial import
thib
parents:
diff changeset
7 * 1998- <masaki-c@is.aist-nara.ac.jp>
223b71206888 Initial import
thib
parents:
diff changeset
8 * 2000- Kazunori Ueno(JAGARL) <jagarl@createor.club.ne.jp>
223b71206888 Initial import
thib
parents:
diff changeset
9 *
223b71206888 Initial import
thib
parents:
diff changeset
10 * This program is free software; you can redistribute it and/or modify
223b71206888 Initial import
thib
parents:
diff changeset
11 * it under the terms of the GNU General Public License as published by
223b71206888 Initial import
thib
parents:
diff changeset
12 * the Free Software Foundation; either version 2 of the License, or
223b71206888 Initial import
thib
parents:
diff changeset
13 * (at your option) any later version.
223b71206888 Initial import
thib
parents:
diff changeset
14 *
223b71206888 Initial import
thib
parents:
diff changeset
15 * This program is distributed in the hope that it will be useful,
223b71206888 Initial import
thib
parents:
diff changeset
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
223b71206888 Initial import
thib
parents:
diff changeset
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
223b71206888 Initial import
thib
parents:
diff changeset
18 * GNU General Public License for more details.
223b71206888 Initial import
thib
parents:
diff changeset
19 *
27
3a6aaeab7b4e * Fixed a typo in Jagarl's name
thib
parents: 8
diff changeset
20 * You should have received a copy of the GNU General Public License along
3a6aaeab7b4e * Fixed a typo in Jagarl's name
thib
parents: 8
diff changeset
21 * with this program; if not, write to the Free Software Foundation, Inc.,
3a6aaeab7b4e * Fixed a typo in Jagarl's name
thib
parents: 8
diff changeset
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0
223b71206888 Initial import
thib
parents:
diff changeset
23 *
223b71206888 Initial import
thib
parents:
diff changeset
24 */
223b71206888 Initial import
thib
parents:
diff changeset
25
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
26 #include <stdarg.h>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
27 #include <stdio.h>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
28 #include <stdlib.h>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
29 #include <errno.h>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
30 #include <sys/types.h>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
31 #include <unistd.h>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
32 #include <string.h>
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
33 #include "wavfile.h"
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
34 #include "system/file.h"
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
35 #include "music.h"
0
223b71206888 Initial import
thib
parents:
diff changeset
36
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
37 #define BUFFERSIZE 1024
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
38 #define PCM_WAVE_FORMAT 1
0
223b71206888 Initial import
thib
parents:
diff changeset
39
223b71206888 Initial import
thib
parents:
diff changeset
40 /*******************************************************
223b71206888 Initial import
thib
parents:
diff changeset
41 **
223b71206888 Initial import
thib
parents:
diff changeset
42 ** WAVE Header
223b71206888 Initial import
thib
parents:
diff changeset
43 */
223b71206888 Initial import
thib
parents:
diff changeset
44
223b71206888 Initial import
thib
parents:
diff changeset
45 inline int LittleEndian_getDW(const char *b,int index) {
223b71206888 Initial import
thib
parents:
diff changeset
46 int c0, c1, c2, c3;
223b71206888 Initial import
thib
parents:
diff changeset
47 int d0, d1;
223b71206888 Initial import
thib
parents:
diff changeset
48 c0 = *(const unsigned char*)(b + index + 0);
223b71206888 Initial import
thib
parents:
diff changeset
49 c1 = *(const unsigned char*)(b + index + 1);
223b71206888 Initial import
thib
parents:
diff changeset
50 c2 = *(const unsigned char*)(b + index + 2);
223b71206888 Initial import
thib
parents:
diff changeset
51 c3 = *(const unsigned char*)(b + index + 3);
223b71206888 Initial import
thib
parents:
diff changeset
52 d0 = c0 + (c1 << 8);
223b71206888 Initial import
thib
parents:
diff changeset
53 d1 = c2 + (c3 << 8);
223b71206888 Initial import
thib
parents:
diff changeset
54 return d0 + (d1 << 16);
223b71206888 Initial import
thib
parents:
diff changeset
55 }
223b71206888 Initial import
thib
parents:
diff changeset
56
223b71206888 Initial import
thib
parents:
diff changeset
57 inline int LittleEndian_get3B(const char *b,int index) {
223b71206888 Initial import
thib
parents:
diff changeset
58 int c0, c1, c2;
223b71206888 Initial import
thib
parents:
diff changeset
59 c0 = *(const unsigned char*)(b + index + 0);
223b71206888 Initial import
thib
parents:
diff changeset
60 c1 = *(const unsigned char*)(b + index + 1);
223b71206888 Initial import
thib
parents:
diff changeset
61 c2 = *(const unsigned char*)(b + index + 2);
223b71206888 Initial import
thib
parents:
diff changeset
62 return c0 + (c1 << 8) + (c2 << 16);
223b71206888 Initial import
thib
parents:
diff changeset
63 }
223b71206888 Initial import
thib
parents:
diff changeset
64
223b71206888 Initial import
thib
parents:
diff changeset
65 inline int LittleEndian_getW(const char *b,int index) {
223b71206888 Initial import
thib
parents:
diff changeset
66 int c0, c1;
223b71206888 Initial import
thib
parents:
diff changeset
67 c0 = *(const unsigned char*)(b + index + 0);
223b71206888 Initial import
thib
parents:
diff changeset
68 c1 = *(const unsigned char*)(b + index + 1);
223b71206888 Initial import
thib
parents:
diff changeset
69 return c0 + (c1 << 8);
223b71206888 Initial import
thib
parents:
diff changeset
70 }
223b71206888 Initial import
thib
parents:
diff changeset
71
223b71206888 Initial import
thib
parents:
diff changeset
72 inline void LittleEndian_putW(int num, char *b, int index) {
223b71206888 Initial import
thib
parents:
diff changeset
73 int c0, c1;
223b71206888 Initial import
thib
parents:
diff changeset
74 num %= 65536;
223b71206888 Initial import
thib
parents:
diff changeset
75 c0 = num % 256;
223b71206888 Initial import
thib
parents:
diff changeset
76 c1 = num / 256;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
77 b[index] = c0;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
78 b[index+1] = c1;
0
223b71206888 Initial import
thib
parents:
diff changeset
79 }
223b71206888 Initial import
thib
parents:
diff changeset
80
223b71206888 Initial import
thib
parents:
diff changeset
81 typedef struct
223b71206888 Initial import
thib
parents:
diff changeset
82 { u_long dwSize ;
223b71206888 Initial import
thib
parents:
diff changeset
83 u_short wFormatTag ;
223b71206888 Initial import
thib
parents:
diff changeset
84 u_short wChannels ;
223b71206888 Initial import
thib
parents:
diff changeset
85 u_long dwSamplesPerSec ;
223b71206888 Initial import
thib
parents:
diff changeset
86 u_long dwAvgBytesPerSec ;
223b71206888 Initial import
thib
parents:
diff changeset
87 u_short wBlockAlign ;
223b71206888 Initial import
thib
parents:
diff changeset
88 u_short wBitsPerSample ;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
89 } WAVEFORMAT;
0
223b71206888 Initial import
thib
parents:
diff changeset
90
223b71206888 Initial import
thib
parents:
diff changeset
91 typedef struct
223b71206888 Initial import
thib
parents:
diff changeset
92 { char RiffID [4] ;
223b71206888 Initial import
thib
parents:
diff changeset
93 u_long RiffSize ;
223b71206888 Initial import
thib
parents:
diff changeset
94 char WaveID [4] ;
223b71206888 Initial import
thib
parents:
diff changeset
95 char FmtID [4] ;
223b71206888 Initial import
thib
parents:
diff changeset
96 u_long FmtSize ;
223b71206888 Initial import
thib
parents:
diff changeset
97 u_short wFormatTag ;
223b71206888 Initial import
thib
parents:
diff changeset
98 u_short nChannels ;
223b71206888 Initial import
thib
parents:
diff changeset
99 u_long nSamplesPerSec ;
223b71206888 Initial import
thib
parents:
diff changeset
100 u_long nAvgBytesPerSec ;
223b71206888 Initial import
thib
parents:
diff changeset
101 u_short nBlockAlign ;
223b71206888 Initial import
thib
parents:
diff changeset
102 u_short wBitsPerSample ;
223b71206888 Initial import
thib
parents:
diff changeset
103 char DataID [4] ;
223b71206888 Initial import
thib
parents:
diff changeset
104 u_long nDataBytes ;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
105 } WAVE_HEADER;
0
223b71206888 Initial import
thib
parents:
diff changeset
106
223b71206888 Initial import
thib
parents:
diff changeset
107
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
108 static void waveFormatCopy(WAVEFORMAT* wav, char *ptr );
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
109 static char* findchunk(char* s1, const char* s2, size_t n) ;
0
223b71206888 Initial import
thib
parents:
diff changeset
110
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
111 static int WaveHeaderCheck(char *wave_buf,int* channels, u_long* samplerate, int* samplebits, u_long* samples,u_long* datastart)
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
112 {
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
113 static WAVEFORMAT waveformat;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
114 char* ptr;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
115 u_long databytes;
0
223b71206888 Initial import
thib
parents:
diff changeset
116
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
117 if (findchunk(wave_buf, "RIFF", BUFFERSIZE) != wave_buf) {
0
223b71206888 Initial import
thib
parents:
diff changeset
118 fprintf(stderr, "Bad format: Cannot find RIFF file marker");
223b71206888 Initial import
thib
parents:
diff changeset
119 return WR_BADRIFF ;
223b71206888 Initial import
thib
parents:
diff changeset
120 }
223b71206888 Initial import
thib
parents:
diff changeset
121
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
122 if (findchunk(wave_buf, "WAVE", BUFFERSIZE) == NULL) {
0
223b71206888 Initial import
thib
parents:
diff changeset
123 fprintf(stderr, "Bad format: Cannot find WAVE file marker");
223b71206888 Initial import
thib
parents:
diff changeset
124 return WR_BADWAVE ;
223b71206888 Initial import
thib
parents:
diff changeset
125 }
223b71206888 Initial import
thib
parents:
diff changeset
126
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
127 ptr = findchunk(wave_buf, "fmt ", BUFFERSIZE) ;
0
223b71206888 Initial import
thib
parents:
diff changeset
128
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
129 if (ptr == NULL) {
0
223b71206888 Initial import
thib
parents:
diff changeset
130 fprintf(stderr, "Bad format: Cannot find 'fmt' file marker");
223b71206888 Initial import
thib
parents:
diff changeset
131 return WR_BADFORMAT ;
223b71206888 Initial import
thib
parents:
diff changeset
132 }
223b71206888 Initial import
thib
parents:
diff changeset
133
223b71206888 Initial import
thib
parents:
diff changeset
134 ptr += 4 ; /* Move past "fmt ".*/
223b71206888 Initial import
thib
parents:
diff changeset
135 waveFormatCopy( &waveformat, ptr );
223b71206888 Initial import
thib
parents:
diff changeset
136
223b71206888 Initial import
thib
parents:
diff changeset
137 if (waveformat.dwSize != (sizeof (WAVEFORMAT) - sizeof (u_long))) {
223b71206888 Initial import
thib
parents:
diff changeset
138 /* fprintf(stderr, "Bad format: Bad fmt size"); */
223b71206888 Initial import
thib
parents:
diff changeset
139 /* return WR_BADFORMATSIZE ; */
223b71206888 Initial import
thib
parents:
diff changeset
140 }
223b71206888 Initial import
thib
parents:
diff changeset
141
223b71206888 Initial import
thib
parents:
diff changeset
142 if (waveformat.wFormatTag != PCM_WAVE_FORMAT) {
223b71206888 Initial import
thib
parents:
diff changeset
143 fprintf(stderr, "Only supports PCM wave format");
223b71206888 Initial import
thib
parents:
diff changeset
144 return WR_NOTPCMFORMAT ;
223b71206888 Initial import
thib
parents:
diff changeset
145 }
223b71206888 Initial import
thib
parents:
diff changeset
146
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
147 ptr = findchunk(wave_buf, "data", BUFFERSIZE) ;
0
223b71206888 Initial import
thib
parents:
diff changeset
148
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
149 if (ptr == NULL) {
0
223b71206888 Initial import
thib
parents:
diff changeset
150 fprintf(stderr,"Bad format: unable to find 'data' file marker");
223b71206888 Initial import
thib
parents:
diff changeset
151 return WR_NODATACHUNK ;
223b71206888 Initial import
thib
parents:
diff changeset
152 }
223b71206888 Initial import
thib
parents:
diff changeset
153
223b71206888 Initial import
thib
parents:
diff changeset
154 ptr += 4 ; /* Move past "data".*/
223b71206888 Initial import
thib
parents:
diff changeset
155 databytes = LittleEndian_getDW(ptr, 0);
223b71206888 Initial import
thib
parents:
diff changeset
156
223b71206888 Initial import
thib
parents:
diff changeset
157 /* Everything is now cool, so fill in output data.*/
223b71206888 Initial import
thib
parents:
diff changeset
158
223b71206888 Initial import
thib
parents:
diff changeset
159 *channels = waveformat.wChannels;
223b71206888 Initial import
thib
parents:
diff changeset
160 *samplerate = waveformat.dwSamplesPerSec ;
223b71206888 Initial import
thib
parents:
diff changeset
161 *samplebits = waveformat.wBitsPerSample ;
223b71206888 Initial import
thib
parents:
diff changeset
162 *samples = databytes / waveformat.wBlockAlign ;
223b71206888 Initial import
thib
parents:
diff changeset
163
223b71206888 Initial import
thib
parents:
diff changeset
164 *datastart = (u_long)(ptr) + 4;
223b71206888 Initial import
thib
parents:
diff changeset
165
223b71206888 Initial import
thib
parents:
diff changeset
166 if (waveformat.dwSamplesPerSec != waveformat.dwAvgBytesPerSec / waveformat.wBlockAlign) {
223b71206888 Initial import
thib
parents:
diff changeset
167 fprintf(stderr, "Bad file format");
223b71206888 Initial import
thib
parents:
diff changeset
168 return WR_BADFORMATDATA ;
223b71206888 Initial import
thib
parents:
diff changeset
169 }
223b71206888 Initial import
thib
parents:
diff changeset
170
223b71206888 Initial import
thib
parents:
diff changeset
171 if (waveformat.dwSamplesPerSec != waveformat.dwAvgBytesPerSec / waveformat.wChannels / ((waveformat.wBitsPerSample == 16) ? 2 : 1)) {
223b71206888 Initial import
thib
parents:
diff changeset
172 fprintf(stderr, "Bad file format");
223b71206888 Initial import
thib
parents:
diff changeset
173 return WR_BADFORMATDATA ;
223b71206888 Initial import
thib
parents:
diff changeset
174 }
223b71206888 Initial import
thib
parents:
diff changeset
175
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
176 return 0;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
177 } /* WaveHeaderCheck*/
0
223b71206888 Initial import
thib
parents:
diff changeset
178
223b71206888 Initial import
thib
parents:
diff changeset
179
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
180 static char* findchunk(char* pstart, const char* fourcc, size_t n) {
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
181 char *pend;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
182 int k, test;
0
223b71206888 Initial import
thib
parents:
diff changeset
183
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
184 pend = pstart + n;
0
223b71206888 Initial import
thib
parents:
diff changeset
185
223b71206888 Initial import
thib
parents:
diff changeset
186 while (pstart < pend)
223b71206888 Initial import
thib
parents:
diff changeset
187 {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
188 if (*pstart == *fourcc) { /* found match for first char*/
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
189 test = 1 ;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
190 for (k = 1 ; fourcc[k] != 0 ; k++)
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
191 test = (test ? ( pstart[k] == fourcc[k] ) : 0) ;
0
223b71206888 Initial import
thib
parents:
diff changeset
192 if (test)
223b71206888 Initial import
thib
parents:
diff changeset
193 return pstart ;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
194 } ; /* if*/
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
195 pstart++;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
196 } /* while lpstart*/
0
223b71206888 Initial import
thib
parents:
diff changeset
197
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
198 return NULL;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
199 } /* findchuck*/
0
223b71206888 Initial import
thib
parents:
diff changeset
200
223b71206888 Initial import
thib
parents:
diff changeset
201 static void waveFormatCopy( WAVEFORMAT* wav, char *ptr ) {
223b71206888 Initial import
thib
parents:
diff changeset
202 wav->dwSize = LittleEndian_getDW( ptr, 0 );
223b71206888 Initial import
thib
parents:
diff changeset
203 wav->wFormatTag = LittleEndian_getW( ptr, 4 );
223b71206888 Initial import
thib
parents:
diff changeset
204 wav->wChannels = LittleEndian_getW( ptr, 6 );
223b71206888 Initial import
thib
parents:
diff changeset
205 wav->dwSamplesPerSec = LittleEndian_getDW( ptr, 8 );
223b71206888 Initial import
thib
parents:
diff changeset
206 wav->dwAvgBytesPerSec = LittleEndian_getDW( ptr, 12 );
223b71206888 Initial import
thib
parents:
diff changeset
207 wav->wBlockAlign = LittleEndian_getW( ptr, 16 );
223b71206888 Initial import
thib
parents:
diff changeset
208 wav->wBitsPerSample = LittleEndian_getW( ptr, 18 );
223b71206888 Initial import
thib
parents:
diff changeset
209 }
223b71206888 Initial import
thib
parents:
diff changeset
210
223b71206888 Initial import
thib
parents:
diff changeset
211 static char* WavGetInfo(WAVFILE* wfile, char *data) {
223b71206888 Initial import
thib
parents:
diff changeset
212 int e; /* Saved errno value */
223b71206888 Initial import
thib
parents:
diff changeset
213 int channels; /* Channels recorded in this wav file */
223b71206888 Initial import
thib
parents:
diff changeset
214 u_long samplerate; /* Sampling rate */
223b71206888 Initial import
thib
parents:
diff changeset
215 int sample_bits; /* data bit size (8/12/16) */
223b71206888 Initial import
thib
parents:
diff changeset
216 u_long samples; /* The number of samples in this file */
223b71206888 Initial import
thib
parents:
diff changeset
217 u_long datastart; /* The offset to the wav data */
223b71206888 Initial import
thib
parents:
diff changeset
218
223b71206888 Initial import
thib
parents:
diff changeset
219 if ( (e = WaveHeaderCheck(data,
223b71206888 Initial import
thib
parents:
diff changeset
220 &channels,&samplerate,
223b71206888 Initial import
thib
parents:
diff changeset
221 &sample_bits,&samples,&datastart) != 0 )) {
223b71206888 Initial import
thib
parents:
diff changeset
222 fprintf(stderr,"WavGetInfo(): Reading WAV header\n");
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
223 return NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
224 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
225
0
223b71206888 Initial import
thib
parents:
diff changeset
226 /*
223b71206888 Initial import
thib
parents:
diff changeset
227 * Copy WAV data over to WAVFILE struct:
223b71206888 Initial import
thib
parents:
diff changeset
228 */
223b71206888 Initial import
thib
parents:
diff changeset
229 wfile->wavinfo.Channels = channels;
223b71206888 Initial import
thib
parents:
diff changeset
230
223b71206888 Initial import
thib
parents:
diff changeset
231 wfile->wavinfo.SamplingRate = (unsigned int) samplerate;
223b71206888 Initial import
thib
parents:
diff changeset
232 wfile->wavinfo.DataBits = (unsigned short) sample_bits;
223b71206888 Initial import
thib
parents:
diff changeset
233
223b71206888 Initial import
thib
parents:
diff changeset
234 return (char *) datastart;
223b71206888 Initial import
thib
parents:
diff changeset
235 }
223b71206888 Initial import
thib
parents:
diff changeset
236
223b71206888 Initial import
thib
parents:
diff changeset
237 /************************************************************:
223b71206888 Initial import
thib
parents:
diff changeset
238 **
223b71206888 Initial import
thib
parents:
diff changeset
239 ** WAVFILE stream reader
223b71206888 Initial import
thib
parents:
diff changeset
240 */
223b71206888 Initial import
thib
parents:
diff changeset
241
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
242 #include <SDL_mixer.h>
0
223b71206888 Initial import
thib
parents:
diff changeset
243 WAVFILE::WAVFILE(void) {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
244 wavinfo.SamplingRate = 0;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
245 wavinfo.Channels = 1;
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
246 wavinfo.DataBits = 0;
0
223b71206888 Initial import
thib
parents:
diff changeset
247 }
223b71206888 Initial import
thib
parents:
diff changeset
248
223b71206888 Initial import
thib
parents:
diff changeset
249 int WAVFILE_Stream::Read(char* in_buf, int blksize, int length) {
223b71206888 Initial import
thib
parents:
diff changeset
250 /* ¥Õ¥¡¥¤¥ë¤ÎÆɤ߹þ¤ß */
223b71206888 Initial import
thib
parents:
diff changeset
251 if (data_length == 0 && stream_length == 0) return -1;
223b71206888 Initial import
thib
parents:
diff changeset
252 /* wf->data ¤Ë¥Ç¡¼¥¿¤Î»Ä¤ê¤¬¤¢¤ì¤Ð¤½¤ì¤âÆɤ߹þ¤à */
223b71206888 Initial import
thib
parents:
diff changeset
253 if (data_length > blksize*length) {
223b71206888 Initial import
thib
parents:
diff changeset
254 memcpy(in_buf, data, blksize*length);
223b71206888 Initial import
thib
parents:
diff changeset
255 data += blksize * length;
223b71206888 Initial import
thib
parents:
diff changeset
256 data_length -= blksize * length;
223b71206888 Initial import
thib
parents:
diff changeset
257 return length;
223b71206888 Initial import
thib
parents:
diff changeset
258 }
223b71206888 Initial import
thib
parents:
diff changeset
259 memcpy(in_buf, data, data_length);
223b71206888 Initial import
thib
parents:
diff changeset
260 if (stream_length != -1 && stream_length < blksize*length-data_length) {
223b71206888 Initial import
thib
parents:
diff changeset
261 length = (stream_length+data_length+blksize-1)/blksize;
223b71206888 Initial import
thib
parents:
diff changeset
262 }
223b71206888 Initial import
thib
parents:
diff changeset
263 int read_len = 0;
223b71206888 Initial import
thib
parents:
diff changeset
264 if (blksize*length-data_length > 0) {
223b71206888 Initial import
thib
parents:
diff changeset
265 read_len = fread(in_buf+data_length, 1, blksize*length-data_length, stream);
223b71206888 Initial import
thib
parents:
diff changeset
266 if (stream_length != -1 && stream_length > read_len) stream_length -= read_len;
223b71206888 Initial import
thib
parents:
diff changeset
267 if (feof(stream)) stream_length = 0; // end of file
223b71206888 Initial import
thib
parents:
diff changeset
268 } else {
223b71206888 Initial import
thib
parents:
diff changeset
269 stream_length = 0; // all data were read
223b71206888 Initial import
thib
parents:
diff changeset
270 }
223b71206888 Initial import
thib
parents:
diff changeset
271 int blklen = (read_len + data_length) / blksize;
223b71206888 Initial import
thib
parents:
diff changeset
272 data_length = 0;
223b71206888 Initial import
thib
parents:
diff changeset
273 return blklen;
223b71206888 Initial import
thib
parents:
diff changeset
274 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
275
0
223b71206888 Initial import
thib
parents:
diff changeset
276 void WAVFILE_Stream::Seek(int count) {
223b71206888 Initial import
thib
parents:
diff changeset
277 int blksize = 1;
223b71206888 Initial import
thib
parents:
diff changeset
278 /* block size ¤ÎÀßÄê */
223b71206888 Initial import
thib
parents:
diff changeset
279 blksize *= wavinfo.Channels * (wavinfo.DataBits/8);
223b71206888 Initial import
thib
parents:
diff changeset
280 data_length = 0;
223b71206888 Initial import
thib
parents:
diff changeset
281 stream_length = stream_length_orig - stream_top - count*blksize;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
282 fseek(stream, count*blksize+stream_top, SEEK_SET);
0
223b71206888 Initial import
thib
parents:
diff changeset
283 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
284
0
223b71206888 Initial import
thib
parents:
diff changeset
285 WAVFILE_Stream::WAVFILE_Stream(FILE* _stream, int _length) {
223b71206888 Initial import
thib
parents:
diff changeset
286 stream = _stream;
223b71206888 Initial import
thib
parents:
diff changeset
287 stream_length = _length;
223b71206888 Initial import
thib
parents:
diff changeset
288 stream_length_orig = _length;
223b71206888 Initial import
thib
parents:
diff changeset
289 data_orig = new char[1024];
223b71206888 Initial import
thib
parents:
diff changeset
290 data = data_orig;
223b71206888 Initial import
thib
parents:
diff changeset
291 data_length = 1024;
223b71206888 Initial import
thib
parents:
diff changeset
292 if (stream_length != -1 && stream_length < data_length) {
223b71206888 Initial import
thib
parents:
diff changeset
293 data_length = stream_length;
223b71206888 Initial import
thib
parents:
diff changeset
294 }
223b71206888 Initial import
thib
parents:
diff changeset
295 fread(data, data_length, 1, stream);
223b71206888 Initial import
thib
parents:
diff changeset
296 if (stream_length != -1)
223b71206888 Initial import
thib
parents:
diff changeset
297 stream_length -= data_length;
223b71206888 Initial import
thib
parents:
diff changeset
298 data = WavGetInfo(this, data);
223b71206888 Initial import
thib
parents:
diff changeset
299 if (data == 0) {
223b71206888 Initial import
thib
parents:
diff changeset
300 stream_length = 0;
223b71206888 Initial import
thib
parents:
diff changeset
301 data_length = 0;
223b71206888 Initial import
thib
parents:
diff changeset
302 return;
223b71206888 Initial import
thib
parents:
diff changeset
303 }
223b71206888 Initial import
thib
parents:
diff changeset
304 stream_top = data - data_orig;
223b71206888 Initial import
thib
parents:
diff changeset
305 data_length -= data - data_orig;
223b71206888 Initial import
thib
parents:
diff changeset
306 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
307
0
223b71206888 Initial import
thib
parents:
diff changeset
308 WAVFILE_Stream::~WAVFILE_Stream() {
223b71206888 Initial import
thib
parents:
diff changeset
309 if (data_orig) delete data_orig;
223b71206888 Initial import
thib
parents:
diff changeset
310 if (stream) fclose(stream);
223b71206888 Initial import
thib
parents:
diff changeset
311 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
312
0
223b71206888 Initial import
thib
parents:
diff changeset
313 /************************************************************:
223b71206888 Initial import
thib
parents:
diff changeset
314 **
223b71206888 Initial import
thib
parents:
diff changeset
315 ** WAVE format converter with SDL_audio
223b71206888 Initial import
thib
parents:
diff changeset
316 */
223b71206888 Initial import
thib
parents:
diff changeset
317 WAVFILE* WAVFILE::MakeConverter(WAVFILE* new_reader) {
223b71206888 Initial import
thib
parents:
diff changeset
318 bool need = false;
223b71206888 Initial import
thib
parents:
diff changeset
319 if (new_reader->wavinfo.SamplingRate != freq) need = true;
223b71206888 Initial import
thib
parents:
diff changeset
320 if (new_reader->wavinfo.Channels != channels) need = true;
223b71206888 Initial import
thib
parents:
diff changeset
321 if (format == AUDIO_S8) {
223b71206888 Initial import
thib
parents:
diff changeset
322 if (new_reader->wavinfo.DataBits != 8) need = true;
223b71206888 Initial import
thib
parents:
diff changeset
323 } else if (format == AUDIO_S16) {
223b71206888 Initial import
thib
parents:
diff changeset
324 if (new_reader->wavinfo.DataBits != 16) need = true;
223b71206888 Initial import
thib
parents:
diff changeset
325 } else {
223b71206888 Initial import
thib
parents:
diff changeset
326 need = true;
223b71206888 Initial import
thib
parents:
diff changeset
327 }
223b71206888 Initial import
thib
parents:
diff changeset
328 if (!need) return new_reader;
223b71206888 Initial import
thib
parents:
diff changeset
329 /* ÊÑ´¹¤â¤È¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤òÆÀ¤ë */
223b71206888 Initial import
thib
parents:
diff changeset
330 int from_format;
223b71206888 Initial import
thib
parents:
diff changeset
331 if (new_reader->wavinfo.DataBits == 8) from_format = AUDIO_S8;
223b71206888 Initial import
thib
parents:
diff changeset
332 else from_format = AUDIO_S16;
223b71206888 Initial import
thib
parents:
diff changeset
333 SDL_AudioCVT* cvt = new SDL_AudioCVT;
223b71206888 Initial import
thib
parents:
diff changeset
334 int ret = SDL_BuildAudioCVT(cvt, from_format, new_reader->wavinfo.Channels, freq,
223b71206888 Initial import
thib
parents:
diff changeset
335 format, 2, freq);
223b71206888 Initial import
thib
parents:
diff changeset
336 if (ret == -1) {
223b71206888 Initial import
thib
parents:
diff changeset
337 delete cvt;
223b71206888 Initial import
thib
parents:
diff changeset
338 fprintf(stderr,"Cannot make wave file converter!!!\n");
223b71206888 Initial import
thib
parents:
diff changeset
339 return new_reader;
223b71206888 Initial import
thib
parents:
diff changeset
340 }
223b71206888 Initial import
thib
parents:
diff changeset
341 WAVFILE_Converter* conv = new WAVFILE_Converter(new_reader, cvt);
223b71206888 Initial import
thib
parents:
diff changeset
342 return conv;
223b71206888 Initial import
thib
parents:
diff changeset
343 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
344
0
223b71206888 Initial import
thib
parents:
diff changeset
345 WAVFILE_Converter::WAVFILE_Converter(WAVFILE* _orig, SDL_AudioCVT* _cvt) {
223b71206888 Initial import
thib
parents:
diff changeset
346 original = _orig;
223b71206888 Initial import
thib
parents:
diff changeset
347 cvt = _cvt;
223b71206888 Initial import
thib
parents:
diff changeset
348 //datasize = 4096*4;
223b71206888 Initial import
thib
parents:
diff changeset
349 datasize = 48000;
223b71206888 Initial import
thib
parents:
diff changeset
350 cvt->buf = new Uint8[datasize*cvt->len_mult];
223b71206888 Initial import
thib
parents:
diff changeset
351 cvt->len = 0;
223b71206888 Initial import
thib
parents:
diff changeset
352 tmpbuf = new char[datasize*cvt->len_mult + 1024];
223b71206888 Initial import
thib
parents:
diff changeset
353 memset(tmpbuf, 0, datasize*cvt->len_mult+1024);
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
354 }
0
223b71206888 Initial import
thib
parents:
diff changeset
355
223b71206888 Initial import
thib
parents:
diff changeset
356 static int conv_wave_rate(short* in_buf, int length, int in_rate, int out_rate, char* tmpbuf);
223b71206888 Initial import
thib
parents:
diff changeset
357 WAVFILE_Converter::~WAVFILE_Converter() {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
358 if (cvt != NULL) {
7
fa8511a21d05 Fixes somes memory leaks
thib
parents: 0
diff changeset
359 if (cvt->buf) delete[] cvt->buf;
0
223b71206888 Initial import
thib
parents:
diff changeset
360 delete cvt;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
361 cvt = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
362 }
8
55b577e5f5b5 Some memory leaks fixed
thib
parents: 7
diff changeset
363 delete[] tmpbuf;
0
223b71206888 Initial import
thib
parents:
diff changeset
364 if (original) delete original;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
365 original = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
366 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
367
0
223b71206888 Initial import
thib
parents:
diff changeset
368 int WAVFILE_Converter::Read(char* buf, int blksize, int blklen) {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
369 if (original == NULL || cvt == NULL) return -1;
0
223b71206888 Initial import
thib
parents:
diff changeset
370 int copied_length = 0;
223b71206888 Initial import
thib
parents:
diff changeset
371 if (cvt->len < blksize*blklen) {
223b71206888 Initial import
thib
parents:
diff changeset
372 memcpy(buf, cvt->buf, cvt->len);
223b71206888 Initial import
thib
parents:
diff changeset
373 copied_length += cvt->len;
223b71206888 Initial import
thib
parents:
diff changeset
374 do {
223b71206888 Initial import
thib
parents:
diff changeset
375 int cnt = original->Read((char*)cvt->buf, 1, datasize);
223b71206888 Initial import
thib
parents:
diff changeset
376 if (cnt <= 0) {
223b71206888 Initial import
thib
parents:
diff changeset
377 cvt->len = 0;
223b71206888 Initial import
thib
parents:
diff changeset
378 break;
223b71206888 Initial import
thib
parents:
diff changeset
379 }
223b71206888 Initial import
thib
parents:
diff changeset
380 cvt->len = cnt;
223b71206888 Initial import
thib
parents:
diff changeset
381 SDL_ConvertAudio(cvt);
223b71206888 Initial import
thib
parents:
diff changeset
382 if (freq < original->wavinfo.SamplingRate) { // rate conversion ¤Ï SDL_ConvertAudio ¤Ç¤Ï¤¦¤Þ¤¯¹Ô¤«¤Ê¤¤
223b71206888 Initial import
thib
parents:
diff changeset
383 // 48000Hz -> 44100Hz or 22050Hz ¤Ê¤É¤òÁÛÄê
223b71206888 Initial import
thib
parents:
diff changeset
384 // Ťµ¤Ïû¤¯¤Ê¤ë¤Ï¤º¤Ê¤Î¤Ç¡¢Æä˽èÍý¤Ï¤Ê¤·
223b71206888 Initial import
thib
parents:
diff changeset
385 cvt->len = conv_wave_rate( (short*)(cvt->buf), cvt->len_cvt/4, original->wavinfo.SamplingRate, freq, tmpbuf);
223b71206888 Initial import
thib
parents:
diff changeset
386 cvt->len *= 4;
223b71206888 Initial import
thib
parents:
diff changeset
387 } else {
223b71206888 Initial import
thib
parents:
diff changeset
388 cvt->len = cvt->len_cvt;
223b71206888 Initial import
thib
parents:
diff changeset
389 }
223b71206888 Initial import
thib
parents:
diff changeset
390 if (cvt->len+copied_length > blksize*blklen) break;
223b71206888 Initial import
thib
parents:
diff changeset
391 memcpy(buf+copied_length, cvt->buf, cvt->len);
223b71206888 Initial import
thib
parents:
diff changeset
392 copied_length += cvt->len;
223b71206888 Initial import
thib
parents:
diff changeset
393 } while(1);
223b71206888 Initial import
thib
parents:
diff changeset
394 }
223b71206888 Initial import
thib
parents:
diff changeset
395 if (cvt->len == 0 && copied_length == 0) return -1;
223b71206888 Initial import
thib
parents:
diff changeset
396 else if (cvt->len > 0) {
223b71206888 Initial import
thib
parents:
diff changeset
397 int len = blksize * blklen - copied_length;
223b71206888 Initial import
thib
parents:
diff changeset
398 memcpy(buf+copied_length, cvt->buf, len);
223b71206888 Initial import
thib
parents:
diff changeset
399 memmove(cvt->buf, cvt->buf+len, cvt->len-len);
223b71206888 Initial import
thib
parents:
diff changeset
400 copied_length += len;
223b71206888 Initial import
thib
parents:
diff changeset
401 cvt->len -= len;
223b71206888 Initial import
thib
parents:
diff changeset
402 }
223b71206888 Initial import
thib
parents:
diff changeset
403 return copied_length / blksize;
223b71206888 Initial import
thib
parents:
diff changeset
404 }
223b71206888 Initial import
thib
parents:
diff changeset
405 /* format ¤Ï signed, 16bit, little endian, stereo ¤È·è¤á¤¦¤Á
223b71206888 Initial import
thib
parents:
diff changeset
406 ** ¾ì¹ç¤Ë¤è¤Ã¤Æ¤¤¤Ï big endian ¤Ë¤Ê¤ë¤³¤È¤â¤¢¤ë¤«¤â¡£
223b71206888 Initial import
thib
parents:
diff changeset
407 */
223b71206888 Initial import
thib
parents:
diff changeset
408 static int conv_wave_rate(short* in_buf, int length, int in_rate, int out_rate, char* tmpbuf) {
223b71206888 Initial import
thib
parents:
diff changeset
409 int input_rate = in_rate;
223b71206888 Initial import
thib
parents:
diff changeset
410 int output_rate = out_rate;
223b71206888 Initial import
thib
parents:
diff changeset
411 double input_rate_d = input_rate, output_rate_d = output_rate;
223b71206888 Initial import
thib
parents:
diff changeset
412 double dtime; int outlen; short* out, * out_orig; int next_sample1, next_sample2;
223b71206888 Initial import
thib
parents:
diff changeset
413 short* in_buf_orig = in_buf;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
414 int i, time;
0
223b71206888 Initial import
thib
parents:
diff changeset
415
223b71206888 Initial import
thib
parents:
diff changeset
416 if (input_rate == output_rate) return length;
223b71206888 Initial import
thib
parents:
diff changeset
417 if (length <= 0) return 0;
223b71206888 Initial import
thib
parents:
diff changeset
418 /* °ìÈ̤μþÇÈ¿ôÊÑ´¹¡§Àþ·¿Êä´° */
223b71206888 Initial import
thib
parents:
diff changeset
419 int& first_flag = *(int*)(tmpbuf);
223b71206888 Initial import
thib
parents:
diff changeset
420 int& prev_time = *(int*)(tmpbuf+4);
223b71206888 Initial import
thib
parents:
diff changeset
421 int& prev_sample1 = *(int*)(tmpbuf+8);
223b71206888 Initial import
thib
parents:
diff changeset
422 int& prev_sample2 = *(int*)(tmpbuf+12);
223b71206888 Initial import
thib
parents:
diff changeset
423 out = (short*)(tmpbuf+16);
223b71206888 Initial import
thib
parents:
diff changeset
424 /* ½é¤á¤Æ¤Ê¤é¥Ç¡¼¥¿¤ò½é´ü²½ */
223b71206888 Initial import
thib
parents:
diff changeset
425 if (first_flag == 0) {
223b71206888 Initial import
thib
parents:
diff changeset
426 first_flag = 1;
223b71206888 Initial import
thib
parents:
diff changeset
427 prev_time = 0;
223b71206888 Initial import
thib
parents:
diff changeset
428 prev_sample1 = short(read_little_endian_short((char*)(in_buf++)));
223b71206888 Initial import
thib
parents:
diff changeset
429 prev_sample2 = short(read_little_endian_short((char*)(in_buf++)));
223b71206888 Initial import
thib
parents:
diff changeset
430 length--;
223b71206888 Initial import
thib
parents:
diff changeset
431 }
223b71206888 Initial import
thib
parents:
diff changeset
432 /* º£²óºîÀ®¤¹¤ë¥Ç¡¼¥¿Î̤òÆÀ¤ë */
223b71206888 Initial import
thib
parents:
diff changeset
433 dtime = prev_time + length * output_rate_d;
223b71206888 Initial import
thib
parents:
diff changeset
434 outlen = (int)(dtime / input_rate_d);
223b71206888 Initial import
thib
parents:
diff changeset
435 out_orig = out;
223b71206888 Initial import
thib
parents:
diff changeset
436 if (first_flag == 1) {
223b71206888 Initial import
thib
parents:
diff changeset
437 write_little_endian_short((char*)out, prev_sample1);
223b71206888 Initial import
thib
parents:
diff changeset
438 out++;
223b71206888 Initial import
thib
parents:
diff changeset
439 write_little_endian_short((char*)out, prev_sample2);
223b71206888 Initial import
thib
parents:
diff changeset
440 out++;
223b71206888 Initial import
thib
parents:
diff changeset
441 }
223b71206888 Initial import
thib
parents:
diff changeset
442 dtime -= input_rate_d*outlen; /* ¼¡¤Î prev_time */
223b71206888 Initial import
thib
parents:
diff changeset
443
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
444 time = 0;
0
223b71206888 Initial import
thib
parents:
diff changeset
445 next_sample1 = short(read_little_endian_short((char*)(in_buf++)));
223b71206888 Initial import
thib
parents:
diff changeset
446 next_sample2 = short(read_little_endian_short((char*)(in_buf++)));
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
447 for (i=0; i < outlen; i++) {
0
223b71206888 Initial import
thib
parents:
diff changeset
448 /* double ¤Ç·×»»¤·¤Æ¤ß¤¿¤±¤É¤½¤¦´Êñ¤Ë¤Ï¹â®²½¤Ï̵Íý¤é¤·¤¤ */
223b71206888 Initial import
thib
parents:
diff changeset
449 /* ¤Ê¤ª¡¢ÊÑ´¹¤Ï 1ʬ¤Î¥Ç¡¼¥¿¤Ë1ÉÃÄøÅÙ¤«¤«¤ë(Celeron 700MHz) */
223b71206888 Initial import
thib
parents:
diff changeset
450 time += input_rate;
223b71206888 Initial import
thib
parents:
diff changeset
451 while(time-prev_time>output_rate) {
223b71206888 Initial import
thib
parents:
diff changeset
452 prev_sample1 = next_sample1;
223b71206888 Initial import
thib
parents:
diff changeset
453 next_sample1 = short(read_little_endian_short((char*)(in_buf++)));
223b71206888 Initial import
thib
parents:
diff changeset
454 prev_sample2 = next_sample2;
223b71206888 Initial import
thib
parents:
diff changeset
455 next_sample2 = short(read_little_endian_short((char*)(in_buf++)));
223b71206888 Initial import
thib
parents:
diff changeset
456 prev_time += output_rate;
223b71206888 Initial import
thib
parents:
diff changeset
457 }
223b71206888 Initial import
thib
parents:
diff changeset
458 write_little_endian_short((char*)out,
223b71206888 Initial import
thib
parents:
diff changeset
459 ((time-prev_time)*next_sample1 +
223b71206888 Initial import
thib
parents:
diff changeset
460 (input_rate-time+prev_time)*prev_sample1) / input_rate);
223b71206888 Initial import
thib
parents:
diff changeset
461 out++;
223b71206888 Initial import
thib
parents:
diff changeset
462 write_little_endian_short((char*)out,
223b71206888 Initial import
thib
parents:
diff changeset
463 ((time-prev_time)*next_sample2 +
223b71206888 Initial import
thib
parents:
diff changeset
464 (input_rate-time+prev_time)*prev_sample2) / input_rate);
223b71206888 Initial import
thib
parents:
diff changeset
465 *out++;
223b71206888 Initial import
thib
parents:
diff changeset
466 }
223b71206888 Initial import
thib
parents:
diff changeset
467 prev_time += output_rate; prev_time -= input_rate * outlen;
223b71206888 Initial import
thib
parents:
diff changeset
468 prev_sample1 = next_sample1; prev_sample2 = next_sample2;
223b71206888 Initial import
thib
parents:
diff changeset
469 if (first_flag == 1) {
223b71206888 Initial import
thib
parents:
diff changeset
470 outlen++; first_flag = 2;
223b71206888 Initial import
thib
parents:
diff changeset
471 }
223b71206888 Initial import
thib
parents:
diff changeset
472 memcpy(in_buf_orig, out_orig, outlen*2*sizeof(short));
223b71206888 Initial import
thib
parents:
diff changeset
473 return outlen;
223b71206888 Initial import
thib
parents:
diff changeset
474 }
223b71206888 Initial import
thib
parents:
diff changeset
475
223b71206888 Initial import
thib
parents:
diff changeset
476
223b71206888 Initial import
thib
parents:
diff changeset
477 /************************************************************:
223b71206888 Initial import
thib
parents:
diff changeset
478 **
223b71206888 Initial import
thib
parents:
diff changeset
479 ** MP3FILE stream reader
223b71206888 Initial import
thib
parents:
diff changeset
480 */
223b71206888 Initial import
thib
parents:
diff changeset
481
223b71206888 Initial import
thib
parents:
diff changeset
482 int WAVFILE::freq = 48000;
223b71206888 Initial import
thib
parents:
diff changeset
483 int WAVFILE::channels = 2;
223b71206888 Initial import
thib
parents:
diff changeset
484 int WAVFILE::format = MIX_DEFAULT_FORMAT;
223b71206888 Initial import
thib
parents:
diff changeset
485
223b71206888 Initial import
thib
parents:
diff changeset
486 #if HAVE_LIBMAD
223b71206888 Initial import
thib
parents:
diff changeset
487
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
488 #include <mad.h>
0
223b71206888 Initial import
thib
parents:
diff changeset
489 #define MPEG_BUFSZ 40000 /* 2.5 s at 128 kbps; 1 s at 320 kbps */
223b71206888 Initial import
thib
parents:
diff changeset
490 struct MP3FILE_impl {
223b71206888 Initial import
thib
parents:
diff changeset
491 enum { PREPARE, RUN, WRITE, DONE} status;
223b71206888 Initial import
thib
parents:
diff changeset
492 struct mad_decoder decoder;
223b71206888 Initial import
thib
parents:
diff changeset
493 char* data;
223b71206888 Initial import
thib
parents:
diff changeset
494 int data_len;
223b71206888 Initial import
thib
parents:
diff changeset
495 char* write_data;
223b71206888 Initial import
thib
parents:
diff changeset
496 unsigned int write_data_len;
223b71206888 Initial import
thib
parents:
diff changeset
497 unsigned int write_pointer;
223b71206888 Initial import
thib
parents:
diff changeset
498 unsigned int src_pointer;
223b71206888 Initial import
thib
parents:
diff changeset
499 FILE* stream;
223b71206888 Initial import
thib
parents:
diff changeset
500 MP3FILE_impl(FILE*);
223b71206888 Initial import
thib
parents:
diff changeset
501 ~MP3FILE_impl();
223b71206888 Initial import
thib
parents:
diff changeset
502 static enum mad_flow callback_read(void *data, struct mad_stream *stream);
223b71206888 Initial import
thib
parents:
diff changeset
503 static enum mad_flow callback_error(void *data, struct mad_stream *stream, struct mad_frame *frame);
223b71206888 Initial import
thib
parents:
diff changeset
504 static enum mad_flow callback_write(void *data, struct mad_header const *header, struct mad_pcm *pcm);
223b71206888 Initial import
thib
parents:
diff changeset
505 enum mad_flow callback_write_impl(struct mad_pcm *pcm);
223b71206888 Initial import
thib
parents:
diff changeset
506 void run(void);
223b71206888 Initial import
thib
parents:
diff changeset
507 };
223b71206888 Initial import
thib
parents:
diff changeset
508
223b71206888 Initial import
thib
parents:
diff changeset
509 MP3FILE_impl::MP3FILE_impl(FILE* _stream) {
223b71206888 Initial import
thib
parents:
diff changeset
510 stream = _stream;
223b71206888 Initial import
thib
parents:
diff changeset
511 data = new char[MPEG_BUFSZ];
223b71206888 Initial import
thib
parents:
diff changeset
512 data_len = 0;
223b71206888 Initial import
thib
parents:
diff changeset
513 src_pointer = 0;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
514 write_data = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
515 write_data_len = 0;
223b71206888 Initial import
thib
parents:
diff changeset
516 write_pointer = 0;
223b71206888 Initial import
thib
parents:
diff changeset
517
223b71206888 Initial import
thib
parents:
diff changeset
518 /* initialize decoder */
223b71206888 Initial import
thib
parents:
diff changeset
519 mad_decoder_init(&decoder, (void*)this, callback_read, 0 /* header */, 0 /* filter */, callback_write,
223b71206888 Initial import
thib
parents:
diff changeset
520 callback_error, 0 /* message */);
223b71206888 Initial import
thib
parents:
diff changeset
521 /* prepare stream */
223b71206888 Initial import
thib
parents:
diff changeset
522 status = PREPARE;
223b71206888 Initial import
thib
parents:
diff changeset
523 *(void**)(&decoder.sync) = malloc(sizeof(*decoder.sync));
223b71206888 Initial import
thib
parents:
diff changeset
524
223b71206888 Initial import
thib
parents:
diff changeset
525 mad_stream_init(&decoder.sync->stream);
223b71206888 Initial import
thib
parents:
diff changeset
526 mad_frame_init(&decoder.sync->frame);
223b71206888 Initial import
thib
parents:
diff changeset
527 mad_synth_init(&decoder.sync->synth);
223b71206888 Initial import
thib
parents:
diff changeset
528
223b71206888 Initial import
thib
parents:
diff changeset
529 mad_stream_options(&decoder.sync->stream, decoder.options);
223b71206888 Initial import
thib
parents:
diff changeset
530
223b71206888 Initial import
thib
parents:
diff changeset
531 while(status != WRITE && status != DONE) run();
223b71206888 Initial import
thib
parents:
diff changeset
532 }
223b71206888 Initial import
thib
parents:
diff changeset
533 MP3FILE_impl::~MP3FILE_impl() {
223b71206888 Initial import
thib
parents:
diff changeset
534 free(decoder.sync);
223b71206888 Initial import
thib
parents:
diff changeset
535 mad_decoder_finish(&decoder);
223b71206888 Initial import
thib
parents:
diff changeset
536 delete[] data;
223b71206888 Initial import
thib
parents:
diff changeset
537 }
223b71206888 Initial import
thib
parents:
diff changeset
538
223b71206888 Initial import
thib
parents:
diff changeset
539 void MP3FILE_impl::run(void) {
223b71206888 Initial import
thib
parents:
diff changeset
540 if (status == DONE) return;
223b71206888 Initial import
thib
parents:
diff changeset
541 struct mad_stream *stream = &decoder.sync->stream;
223b71206888 Initial import
thib
parents:
diff changeset
542 struct mad_frame *frame = &decoder.sync->frame;
223b71206888 Initial import
thib
parents:
diff changeset
543 struct mad_synth *synth = &decoder.sync->synth;
223b71206888 Initial import
thib
parents:
diff changeset
544 if (status == PREPARE) {
223b71206888 Initial import
thib
parents:
diff changeset
545 switch (decoder.input_func(decoder.cb_data, stream)) {
223b71206888 Initial import
thib
parents:
diff changeset
546 case MAD_FLOW_STOP:
223b71206888 Initial import
thib
parents:
diff changeset
547 case MAD_FLOW_BREAK:
223b71206888 Initial import
thib
parents:
diff changeset
548 goto done;
223b71206888 Initial import
thib
parents:
diff changeset
549 case MAD_FLOW_CONTINUE:
223b71206888 Initial import
thib
parents:
diff changeset
550 status = RUN;
223b71206888 Initial import
thib
parents:
diff changeset
551 case MAD_FLOW_IGNORE:
223b71206888 Initial import
thib
parents:
diff changeset
552 break;
223b71206888 Initial import
thib
parents:
diff changeset
553 }
223b71206888 Initial import
thib
parents:
diff changeset
554 return;
223b71206888 Initial import
thib
parents:
diff changeset
555 }
223b71206888 Initial import
thib
parents:
diff changeset
556 if (status == RUN) {
223b71206888 Initial import
thib
parents:
diff changeset
557 if (mad_frame_decode(frame, stream) == -1) {
223b71206888 Initial import
thib
parents:
diff changeset
558 if (!MAD_RECOVERABLE(stream->error)) {
223b71206888 Initial import
thib
parents:
diff changeset
559 status = PREPARE;
223b71206888 Initial import
thib
parents:
diff changeset
560 return;
223b71206888 Initial import
thib
parents:
diff changeset
561 }
223b71206888 Initial import
thib
parents:
diff changeset
562 switch (decoder.error_func((void*)this, stream, frame)) {
223b71206888 Initial import
thib
parents:
diff changeset
563 case MAD_FLOW_STOP:
223b71206888 Initial import
thib
parents:
diff changeset
564 case MAD_FLOW_BREAK:
223b71206888 Initial import
thib
parents:
diff changeset
565 goto done;
223b71206888 Initial import
thib
parents:
diff changeset
566 case MAD_FLOW_IGNORE:
223b71206888 Initial import
thib
parents:
diff changeset
567 status = PREPARE;
223b71206888 Initial import
thib
parents:
diff changeset
568 return;
223b71206888 Initial import
thib
parents:
diff changeset
569 case MAD_FLOW_CONTINUE:
223b71206888 Initial import
thib
parents:
diff changeset
570 default:
223b71206888 Initial import
thib
parents:
diff changeset
571 return;
223b71206888 Initial import
thib
parents:
diff changeset
572 }
223b71206888 Initial import
thib
parents:
diff changeset
573 }
223b71206888 Initial import
thib
parents:
diff changeset
574
223b71206888 Initial import
thib
parents:
diff changeset
575 mad_synth_frame(synth, frame);
223b71206888 Initial import
thib
parents:
diff changeset
576 src_pointer = 0;
223b71206888 Initial import
thib
parents:
diff changeset
577 status = WRITE;
223b71206888 Initial import
thib
parents:
diff changeset
578 return;
223b71206888 Initial import
thib
parents:
diff changeset
579 }
223b71206888 Initial import
thib
parents:
diff changeset
580 if (status == WRITE) {
223b71206888 Initial import
thib
parents:
diff changeset
581 switch (decoder.output_func(decoder.cb_data, &frame->header, &synth->pcm)) {
223b71206888 Initial import
thib
parents:
diff changeset
582 case MAD_FLOW_STOP:
223b71206888 Initial import
thib
parents:
diff changeset
583 case MAD_FLOW_BREAK:
223b71206888 Initial import
thib
parents:
diff changeset
584 goto done;
223b71206888 Initial import
thib
parents:
diff changeset
585 case MAD_FLOW_IGNORE:
223b71206888 Initial import
thib
parents:
diff changeset
586 return;
223b71206888 Initial import
thib
parents:
diff changeset
587 case MAD_FLOW_CONTINUE:
223b71206888 Initial import
thib
parents:
diff changeset
588 status = RUN;
223b71206888 Initial import
thib
parents:
diff changeset
589 break;
223b71206888 Initial import
thib
parents:
diff changeset
590 }
223b71206888 Initial import
thib
parents:
diff changeset
591 if (stream->error == MAD_ERROR_BUFLEN) {
223b71206888 Initial import
thib
parents:
diff changeset
592 stream->error = MAD_ERROR_NONE;
223b71206888 Initial import
thib
parents:
diff changeset
593 status = PREPARE;
223b71206888 Initial import
thib
parents:
diff changeset
594 }
223b71206888 Initial import
thib
parents:
diff changeset
595 return;
223b71206888 Initial import
thib
parents:
diff changeset
596 }
223b71206888 Initial import
thib
parents:
diff changeset
597 done:
223b71206888 Initial import
thib
parents:
diff changeset
598 status = DONE;
223b71206888 Initial import
thib
parents:
diff changeset
599 mad_synth_finish(&decoder.sync->synth);
223b71206888 Initial import
thib
parents:
diff changeset
600 mad_frame_finish(&decoder.sync->frame);
223b71206888 Initial import
thib
parents:
diff changeset
601 mad_stream_finish(&decoder.sync->stream);
223b71206888 Initial import
thib
parents:
diff changeset
602 return;
223b71206888 Initial import
thib
parents:
diff changeset
603 }
223b71206888 Initial import
thib
parents:
diff changeset
604
223b71206888 Initial import
thib
parents:
diff changeset
605 enum mad_flow MP3FILE_impl::callback_read(void *data, struct mad_stream *stream)
223b71206888 Initial import
thib
parents:
diff changeset
606 {
223b71206888 Initial import
thib
parents:
diff changeset
607 MP3FILE_impl* impl = (MP3FILE_impl*)data;
223b71206888 Initial import
thib
parents:
diff changeset
608 if (stream->next_frame) {
223b71206888 Initial import
thib
parents:
diff changeset
609 impl->data_len -= (char*)stream->next_frame - impl->data;
223b71206888 Initial import
thib
parents:
diff changeset
610 memmove(impl->data, (char*)stream->next_frame, impl->data_len);
223b71206888 Initial import
thib
parents:
diff changeset
611 } else {
223b71206888 Initial import
thib
parents:
diff changeset
612 impl->data_len = 0;
223b71206888 Initial import
thib
parents:
diff changeset
613 }
223b71206888 Initial import
thib
parents:
diff changeset
614 int count;
223b71206888 Initial import
thib
parents:
diff changeset
615 if (feof(impl->stream)) {
223b71206888 Initial import
thib
parents:
diff changeset
616 if (stream->next_frame && (char*)stream->next_frame - impl->data > 0) {
223b71206888 Initial import
thib
parents:
diff changeset
617 // There is under processing data
223b71206888 Initial import
thib
parents:
diff changeset
618 count = 0;
223b71206888 Initial import
thib
parents:
diff changeset
619 } else {
223b71206888 Initial import
thib
parents:
diff changeset
620 // all data were processed
223b71206888 Initial import
thib
parents:
diff changeset
621 return MAD_FLOW_STOP;
223b71206888 Initial import
thib
parents:
diff changeset
622 }
223b71206888 Initial import
thib
parents:
diff changeset
623 } else {
223b71206888 Initial import
thib
parents:
diff changeset
624 count = fread(impl->data + impl->data_len, 1, MPEG_BUFSZ-impl->data_len, impl->stream);
223b71206888 Initial import
thib
parents:
diff changeset
625 if (count <= 0) {
223b71206888 Initial import
thib
parents:
diff changeset
626 return MAD_FLOW_BREAK;
223b71206888 Initial import
thib
parents:
diff changeset
627 }
223b71206888 Initial import
thib
parents:
diff changeset
628 }
223b71206888 Initial import
thib
parents:
diff changeset
629 impl->data_len += count;
223b71206888 Initial import
thib
parents:
diff changeset
630 if (impl->data_len < MPEG_BUFSZ) {
223b71206888 Initial import
thib
parents:
diff changeset
631 memset(impl->data + impl->data_len, 0, MPEG_BUFSZ-impl->data_len);
223b71206888 Initial import
thib
parents:
diff changeset
632 }
223b71206888 Initial import
thib
parents:
diff changeset
633 mad_stream_buffer(stream, (unsigned char*)impl->data, impl->data_len);
223b71206888 Initial import
thib
parents:
diff changeset
634 return MAD_FLOW_CONTINUE;
223b71206888 Initial import
thib
parents:
diff changeset
635 }
223b71206888 Initial import
thib
parents:
diff changeset
636
223b71206888 Initial import
thib
parents:
diff changeset
637 enum mad_flow MP3FILE_impl::callback_error(void *data, struct mad_stream *stream, struct mad_frame *frame)
223b71206888 Initial import
thib
parents:
diff changeset
638 {
223b71206888 Initial import
thib
parents:
diff changeset
639 MP3FILE_impl* impl = (MP3FILE_impl*)data;
223b71206888 Initial import
thib
parents:
diff changeset
640 fprintf(stdout, "decoding error 0x%04x (%s) at byte offset %u\n",
223b71206888 Initial import
thib
parents:
diff changeset
641 stream->error, mad_stream_errorstr(stream),
223b71206888 Initial import
thib
parents:
diff changeset
642 ftell(impl->stream) - ((impl->data+impl->data_len)-(char*)stream->this_frame));
223b71206888 Initial import
thib
parents:
diff changeset
643 /* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */
223b71206888 Initial import
thib
parents:
diff changeset
644 return MAD_FLOW_CONTINUE;
223b71206888 Initial import
thib
parents:
diff changeset
645 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
646
0
223b71206888 Initial import
thib
parents:
diff changeset
647 signed int scale(mad_fixed_t sample)
223b71206888 Initial import
thib
parents:
diff changeset
648 {
223b71206888 Initial import
thib
parents:
diff changeset
649 /* round */
223b71206888 Initial import
thib
parents:
diff changeset
650 sample += (1L << (MAD_F_FRACBITS - 16));
223b71206888 Initial import
thib
parents:
diff changeset
651
223b71206888 Initial import
thib
parents:
diff changeset
652 /* clip */
223b71206888 Initial import
thib
parents:
diff changeset
653 if (sample >= MAD_F_ONE)
223b71206888 Initial import
thib
parents:
diff changeset
654 sample = MAD_F_ONE - 1;
223b71206888 Initial import
thib
parents:
diff changeset
655 else if (sample < -MAD_F_ONE)
223b71206888 Initial import
thib
parents:
diff changeset
656 sample = -MAD_F_ONE;
223b71206888 Initial import
thib
parents:
diff changeset
657
223b71206888 Initial import
thib
parents:
diff changeset
658 /* quantize */
223b71206888 Initial import
thib
parents:
diff changeset
659 return sample >> (MAD_F_FRACBITS + 1 - 16);
223b71206888 Initial import
thib
parents:
diff changeset
660 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
661
0
223b71206888 Initial import
thib
parents:
diff changeset
662 enum mad_flow MP3FILE_impl::callback_write(void *data, struct mad_header const *header, struct mad_pcm *pcm)
223b71206888 Initial import
thib
parents:
diff changeset
663 {
223b71206888 Initial import
thib
parents:
diff changeset
664 MP3FILE_impl* pimpl = (MP3FILE_impl*)data;
223b71206888 Initial import
thib
parents:
diff changeset
665 return pimpl->callback_write_impl(pcm);
223b71206888 Initial import
thib
parents:
diff changeset
666 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
667
0
223b71206888 Initial import
thib
parents:
diff changeset
668 enum mad_flow MP3FILE_impl::callback_write_impl(struct mad_pcm *pcm)
223b71206888 Initial import
thib
parents:
diff changeset
669 {
223b71206888 Initial import
thib
parents:
diff changeset
670 if (write_data_len == 0) return MAD_FLOW_IGNORE;
223b71206888 Initial import
thib
parents:
diff changeset
671 mad_fixed_t const *left_ch = pcm->samples[0] + src_pointer;
223b71206888 Initial import
thib
parents:
diff changeset
672 mad_fixed_t const *right_ch = pcm->samples[1] + src_pointer;
223b71206888 Initial import
thib
parents:
diff changeset
673
223b71206888 Initial import
thib
parents:
diff changeset
674 unsigned int nchannels = pcm->channels;
223b71206888 Initial import
thib
parents:
diff changeset
675 unsigned int nsamples = pcm->length - src_pointer;
223b71206888 Initial import
thib
parents:
diff changeset
676 if (write_pointer + nsamples * nchannels * 2 > write_data_len) {
223b71206888 Initial import
thib
parents:
diff changeset
677 nsamples = (write_data_len - write_pointer) / nchannels / 2;
223b71206888 Initial import
thib
parents:
diff changeset
678 }
223b71206888 Initial import
thib
parents:
diff changeset
679 write_data_len &= ~(nchannels*2-1); /* write_data_len ¤Ï¤¢¤é¤«¤¸¤á´Ý¤á¤Æ¤ª¤¯ */
223b71206888 Initial import
thib
parents:
diff changeset
680 src_pointer += nsamples;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
681 if (write_data == NULL) { // skip data write
0
223b71206888 Initial import
thib
parents:
diff changeset
682 write_pointer += nsamples*2*2;
223b71206888 Initial import
thib
parents:
diff changeset
683 } else while(nsamples--) {
223b71206888 Initial import
thib
parents:
diff changeset
684 signed int sample = scale(*left_ch++);
223b71206888 Initial import
thib
parents:
diff changeset
685 write_data[write_pointer++] = sample & 0xff;
223b71206888 Initial import
thib
parents:
diff changeset
686 write_data[write_pointer++] = (sample>>8) & 0xff;
223b71206888 Initial import
thib
parents:
diff changeset
687 if (nchannels == 2) {
223b71206888 Initial import
thib
parents:
diff changeset
688 sample = scale(*right_ch++);
223b71206888 Initial import
thib
parents:
diff changeset
689 }
223b71206888 Initial import
thib
parents:
diff changeset
690 write_data[write_pointer++] = sample & 0xff;
223b71206888 Initial import
thib
parents:
diff changeset
691 write_data[write_pointer++] = (sample>>8) & 0xff;
223b71206888 Initial import
thib
parents:
diff changeset
692 }
223b71206888 Initial import
thib
parents:
diff changeset
693 if (write_pointer >= write_data_len) return MAD_FLOW_IGNORE;
223b71206888 Initial import
thib
parents:
diff changeset
694 else return MAD_FLOW_CONTINUE;
223b71206888 Initial import
thib
parents:
diff changeset
695 }
223b71206888 Initial import
thib
parents:
diff changeset
696
223b71206888 Initial import
thib
parents:
diff changeset
697 MP3FILE::MP3FILE(FILE* stream, int len) {
223b71206888 Initial import
thib
parents:
diff changeset
698 pimpl = new MP3FILE_impl(stream);
223b71206888 Initial import
thib
parents:
diff changeset
699 if (pimpl->status == MP3FILE_impl::DONE) {
223b71206888 Initial import
thib
parents:
diff changeset
700 delete pimpl;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
701 pimpl = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
702 fclose(stream);
223b71206888 Initial import
thib
parents:
diff changeset
703 return;
223b71206888 Initial import
thib
parents:
diff changeset
704 }
223b71206888 Initial import
thib
parents:
diff changeset
705 wavinfo.SamplingRate = pimpl->decoder.sync->synth.pcm.samplerate;
223b71206888 Initial import
thib
parents:
diff changeset
706 wavinfo.Channels = 2;
223b71206888 Initial import
thib
parents:
diff changeset
707 wavinfo.DataBits = 16;
223b71206888 Initial import
thib
parents:
diff changeset
708 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
709
0
223b71206888 Initial import
thib
parents:
diff changeset
710 MP3FILE::~MP3FILE() {
223b71206888 Initial import
thib
parents:
diff changeset
711 if (pimpl) {
223b71206888 Initial import
thib
parents:
diff changeset
712 FILE* s = pimpl->stream;
223b71206888 Initial import
thib
parents:
diff changeset
713 delete pimpl;
223b71206888 Initial import
thib
parents:
diff changeset
714 fclose(s);
223b71206888 Initial import
thib
parents:
diff changeset
715 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
716 pimpl = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
717 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
718
0
223b71206888 Initial import
thib
parents:
diff changeset
719 int MP3FILE::Read(char* buf, int blksize, int blklen) {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
720 if (pimpl == NULL) return -1;
0
223b71206888 Initial import
thib
parents:
diff changeset
721 pimpl->write_data = buf;
223b71206888 Initial import
thib
parents:
diff changeset
722 pimpl->write_data_len = blksize*blklen;
223b71206888 Initial import
thib
parents:
diff changeset
723 pimpl->write_pointer = 0;
223b71206888 Initial import
thib
parents:
diff changeset
724 do {
223b71206888 Initial import
thib
parents:
diff changeset
725 pimpl->run();
223b71206888 Initial import
thib
parents:
diff changeset
726 } while(pimpl->status != MP3FILE_impl::DONE && pimpl->write_pointer < pimpl->write_data_len);
223b71206888 Initial import
thib
parents:
diff changeset
727 return pimpl->write_pointer / blksize;
223b71206888 Initial import
thib
parents:
diff changeset
728 }
223b71206888 Initial import
thib
parents:
diff changeset
729 void MP3FILE::Seek(int count) {
223b71206888 Initial import
thib
parents:
diff changeset
730 FILE* stream = pimpl->stream;
223b71206888 Initial import
thib
parents:
diff changeset
731 delete pimpl;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
732 fseek(stream, 0, SEEK_SET);
0
223b71206888 Initial import
thib
parents:
diff changeset
733 pimpl = new MP3FILE_impl(stream);
223b71206888 Initial import
thib
parents:
diff changeset
734 if (pimpl->status == MP3FILE_impl::DONE) {
223b71206888 Initial import
thib
parents:
diff changeset
735 delete pimpl;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
736 pimpl = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
737 fclose(stream);
223b71206888 Initial import
thib
parents:
diff changeset
738 return;
223b71206888 Initial import
thib
parents:
diff changeset
739 }
223b71206888 Initial import
thib
parents:
diff changeset
740 int blksize = 1;
223b71206888 Initial import
thib
parents:
diff changeset
741 blksize *= wavinfo.Channels * (wavinfo.DataBits/8);
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
742 pimpl->write_data = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
743 pimpl->write_data_len = count * blksize;
223b71206888 Initial import
thib
parents:
diff changeset
744 pimpl->write_pointer = 0;
223b71206888 Initial import
thib
parents:
diff changeset
745 do {
223b71206888 Initial import
thib
parents:
diff changeset
746 pimpl->run();
223b71206888 Initial import
thib
parents:
diff changeset
747 } while(pimpl->status != MP3FILE_impl::DONE && pimpl->write_pointer < pimpl->write_data_len);
223b71206888 Initial import
thib
parents:
diff changeset
748 return;
223b71206888 Initial import
thib
parents:
diff changeset
749 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
750
0
223b71206888 Initial import
thib
parents:
diff changeset
751 #elif USE_SMPEG
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
752 #include <smpeg/smpeg.h>
0
223b71206888 Initial import
thib
parents:
diff changeset
753
223b71206888 Initial import
thib
parents:
diff changeset
754 struct MP3FILE_impl {
223b71206888 Initial import
thib
parents:
diff changeset
755 SMPEG* info;
223b71206888 Initial import
thib
parents:
diff changeset
756 FILE* stream;
223b71206888 Initial import
thib
parents:
diff changeset
757 MP3FILE_impl(FILE*);
223b71206888 Initial import
thib
parents:
diff changeset
758 };
223b71206888 Initial import
thib
parents:
diff changeset
759
223b71206888 Initial import
thib
parents:
diff changeset
760 MP3FILE_impl::MP3FILE_impl(FILE* _stream) {
223b71206888 Initial import
thib
parents:
diff changeset
761 stream = _stream;
223b71206888 Initial import
thib
parents:
diff changeset
762 info = SMPEG_new_descr(fileno(stream), NULL, 0);
48
ed6c21dde840 * use correct format (%p) for pointers
thib
parents: 47
diff changeset
763 fprintf(stderr,"mp3 %p\n",info);
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
764 if (info != NULL && SMPEG_error(info) ) info = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
765 SMPEG_enableaudio(info, 0);
223b71206888 Initial import
thib
parents:
diff changeset
766 SMPEG_enableaudio(info, 1);
223b71206888 Initial import
thib
parents:
diff changeset
767 SMPEG_play(info);
223b71206888 Initial import
thib
parents:
diff changeset
768 }
223b71206888 Initial import
thib
parents:
diff changeset
769
223b71206888 Initial import
thib
parents:
diff changeset
770 MP3FILE::MP3FILE(FILE* stream, int len) {
223b71206888 Initial import
thib
parents:
diff changeset
771 pimpl = new MP3FILE_impl(stream);
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
772 if (pimpl->info == NULL) {
0
223b71206888 Initial import
thib
parents:
diff changeset
773 delete pimpl;
223b71206888 Initial import
thib
parents:
diff changeset
774 fclose(stream);
223b71206888 Initial import
thib
parents:
diff changeset
775 return;
223b71206888 Initial import
thib
parents:
diff changeset
776 }
223b71206888 Initial import
thib
parents:
diff changeset
777 SDL_AudioSpec fmt;
223b71206888 Initial import
thib
parents:
diff changeset
778 SMPEG_wantedSpec(pimpl->info, &fmt);
223b71206888 Initial import
thib
parents:
diff changeset
779 wavinfo.SamplingRate = fmt.freq;
223b71206888 Initial import
thib
parents:
diff changeset
780 wavinfo.Channels = fmt.channels;
223b71206888 Initial import
thib
parents:
diff changeset
781 wavinfo.DataBits = (fmt.format == AUDIO_S8) ? 8:16;
223b71206888 Initial import
thib
parents:
diff changeset
782 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
783
0
223b71206888 Initial import
thib
parents:
diff changeset
784 MP3FILE::~MP3FILE() {
223b71206888 Initial import
thib
parents:
diff changeset
785 if (pimpl && pimpl->info) {
223b71206888 Initial import
thib
parents:
diff changeset
786 if (SMPEG_status(pimpl->info) == SMPEG_PLAYING) SMPEG_stop(pimpl->info);
223b71206888 Initial import
thib
parents:
diff changeset
787 SMPEG_delete(pimpl->info);
223b71206888 Initial import
thib
parents:
diff changeset
788 }
223b71206888 Initial import
thib
parents:
diff changeset
789 if (pimpl) {
223b71206888 Initial import
thib
parents:
diff changeset
790 fclose(pimpl->stream);
223b71206888 Initial import
thib
parents:
diff changeset
791 delete pimpl;
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
792 pimpl = NULL;
0
223b71206888 Initial import
thib
parents:
diff changeset
793 }
223b71206888 Initial import
thib
parents:
diff changeset
794 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
795
0
223b71206888 Initial import
thib
parents:
diff changeset
796 int MP3FILE::Read(char* buf, int blksize, int blklen) {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
797 if (pimpl == NULL || pimpl->info == NULL) return -1;
0
223b71206888 Initial import
thib
parents:
diff changeset
798 int r = SMPEG_playAudio(pimpl->info, (Uint8*)buf, blksize*blklen);
223b71206888 Initial import
thib
parents:
diff changeset
799 if (r <= 0) { // end of file
223b71206888 Initial import
thib
parents:
diff changeset
800 return -1;
223b71206888 Initial import
thib
parents:
diff changeset
801 }
223b71206888 Initial import
thib
parents:
diff changeset
802 return r / blksize;
223b71206888 Initial import
thib
parents:
diff changeset
803 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
804
0
223b71206888 Initial import
thib
parents:
diff changeset
805 void MP3FILE::Seek(int count) {
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
806 if (pimpl == NULL || pimpl->info == NULL) return;
0
223b71206888 Initial import
thib
parents:
diff changeset
807 SMPEG_stop(pimpl->info);
223b71206888 Initial import
thib
parents:
diff changeset
808 SMPEG_rewind(pimpl->info);
223b71206888 Initial import
thib
parents:
diff changeset
809 SMPEG_play(pimpl->info);
223b71206888 Initial import
thib
parents:
diff changeset
810 count /= 4;
223b71206888 Initial import
thib
parents:
diff changeset
811 count *= 4; // reduce noise; possibly SMPEG error
223b71206888 Initial import
thib
parents:
diff changeset
812 char* d = new char[count*channels*2];
223b71206888 Initial import
thib
parents:
diff changeset
813 Read(d,count,channels*2);
223b71206888 Initial import
thib
parents:
diff changeset
814 delete[] d;
223b71206888 Initial import
thib
parents:
diff changeset
815 return;
223b71206888 Initial import
thib
parents:
diff changeset
816 }
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
817
0
223b71206888 Initial import
thib
parents:
diff changeset
818 #else /* SMPEG */
52
15a18fbe6f21 * Known bugs added to the README
thib
parents: 48
diff changeset
819 MP3FILE::MP3FILE(FILE* stream, int len) {pimpl = NULL;}
0
223b71206888 Initial import
thib
parents:
diff changeset
820 MP3FILE::~MP3FILE(){}
223b71206888 Initial import
thib
parents:
diff changeset
821 void MP3FILE::Seek(int count){}
223b71206888 Initial import
thib
parents:
diff changeset
822 int MP3FILE::Read(char* buf, int blksize, int blklen){return -1;}
223b71206888 Initial import
thib
parents:
diff changeset
823 #endif /* SMPEG */