annotate music2/wavfile.cc @ 66:d112357a0ec1

Fix a bug with savegames introduced with changeset c7bcc0ec2267. Warning: savegames created since c7bcc0ec2267 are probably corrupted, you may have to start the game over. If you chose not to do so, you should replace all occurrences of 'TextWindow' by 'TextImplWindow', and 'Text Window' by 'TextImpl Window' in your save files.
author Thibaut Girka <thib@sitedethib.com>
date Sat, 11 Dec 2010 18:36:20 +0100
parents 4416cfac86ae
children
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) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
250 /* ファイルの読み込み */
0
223b71206888 Initial import
thib
parents:
diff changeset
251 if (data_length == 0 && stream_length == 0) return -1;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
252 /* wf->data にデータの残りがあればそれも読み込む */
0
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;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
278 /* block size の設定 */
0
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;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
329 /* 変換もとのフォーマットを得る */
0
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);
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
382 if (freq < original->wavinfo.SamplingRate) { // rate conversion は SDL_ConvertAudio ではうまく行かない
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
383 // 48000Hz -> 44100Hz or 22050Hz などを想定
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
384 // 長さは短くなるはずなので、特に処理はなし
0
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 }
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
405 /* format は signed, 16bit, little endian, stereo と決めうち
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
406 ** 場合によっていは big endian になることもあるかも。
0
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;
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
418 /* 一般の周波数変換:線型補完 */
0
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);
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
424 /* 初めてならデータを初期化 */
0
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 }
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
432 /* 今回作成するデータ量を得る */
0
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 }
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
442 dtime -= input_rate_d*outlen; /* 次の prev_time */
0
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++) {
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
448 /* double で計算してみたけどそう簡単には高速化は無理らしい */
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
449 /* なお、変換は 1分のデータに1秒程度かかる(Celeron 700MHz) */
0
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 }
65
4416cfac86ae Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
679 write_data_len &= ~(nchannels*2-1); /* write_data_len はあらかじめ丸めておく */
0
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 */