2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2002 Alexander König
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Description: This implements the new audiofile class. Unlike earlier
22 versions of terminatorX where wav_read.c was evilishly
23 "#ifdef"ed to support multiple loading strategies this new
24 design allows multiple load_*()-methods/strategies at
25 the same time. (e.g. tx can now try to load a wavfile
26 with the builtin routines and if that fails it'll try
27 to load the file through sox (if available)).
30 #include "tX_audiofile.h"
35 #include "tX_loaddlg.h"
37 tx_audiofile :: tx_audiofile()
39 mem_type=TX_AUDIO_UNDEFINED;
40 file_type=TX_FILE_UNDEFINED;
47 void tx_audiofile :: figure_file_type()
51 ext=strrchr(filename, (int) '.');
59 if (!strcasecmp("wav", ext)) file_type=TX_FILE_WAV;
60 else if (!strncasecmp("mp", ext, 2)) file_type=TX_FILE_MPG123;
61 else if (!strncasecmp("ogg", ext, 2)) file_type=TX_FILE_OGG123;
66 int tx_audiofile :: load(char *p_file_name)
68 int load_err=TX_AUDIO_ERR_NOT_SUPPORTED;
70 strcpy(filename, p_file_name);
76 #ifdef USE_BUILTIN_WAV
77 if ((load_err) && (file_type==TX_FILE_WAV))
80 if (!load_err) return(load_err);
83 #ifdef USE_MPG123_INPUT
84 if ((load_err) && (file_type==TX_FILE_MPG123))
86 load_err=load_mpg123();
91 #ifdef USE_OGG123_INPUT
92 if ((load_err) && (file_type==TX_FILE_OGG123))
94 load_err=load_ogg123();
109 tx_audiofile :: ~tx_audiofile()
123 //munlock(void *mem, memsize);
133 if (mem_type==TX_AUDIO_MMAP)
141 typedef struct tembpuff
143 char buffer[SOX_BLOCKSIZE];
148 static tempbuff *newbuff()
152 nwbf=(tempbuff *) malloc(sizeof(tempbuff));
161 int tx_audiofile :: load_piped()
168 tempbuff* start=NULL;
175 mem_type=TX_AUDIO_LOAD;
177 ld_set_progress(0.5);
181 bytes = fread(w->buffer, 1, SOX_BLOCKSIZE, file);
183 #ifdef BIG_ENDIAN_MACHINE
184 swapbuffer((int16_t *) w->buffer, bytes/sizeof(int16_t));
190 if (!newb) return (TX_AUDIO_ERR_ALLOC);
195 #ifdef BIG_ENDIAN_MACHINE
196 //if (!wav_in.has_host_order) swapbuffer(p, bytes/sizeof(int16_t));
201 pclose(file); file=NULL;
203 if (!allbytes) // Nothing read from pipe -> error
206 return (TX_AUDIO_ERR_PIPE_READ);
209 no_samples=allbytes/sizeof(int16_t);
211 data = (int16_t *) malloc (memsize);
218 newb=(tempbuff*)w->next;
222 return(TX_AUDIO_ERR_ALLOC);
232 memcpy(p, w->buffer, w->used);
234 newb=(tempbuff*) w->next;
238 ld_set_progress(0.5 + 0.5*((gfloat) bytes)/((gfloat) allbytes));
240 p+=(ssize_t) SOX_BLOCKSIZE/sizeof(int16_t);
244 return (TX_AUDIO_SUCCESS);
250 int tx_audiofile :: load_sox()
252 char command[PATH_MAX*2];
254 sprintf(command, SOX_STR, filename);
255 file = popen(command, "r");
257 if (!file) return TX_AUDIO_ERR_SOX;
264 #ifdef USE_MPG123_INPUT
265 int tx_audiofile :: load_mpg123()
267 char command[PATH_MAX*2];
269 sprintf(command, MPG123_STR, filename);
270 file = popen(command, "r");
272 if (!file) return TX_AUDIO_ERR_MPG123;
278 #ifdef USE_OGG123_INPUT
279 int tx_audiofile :: load_ogg123()
281 char command[PATH_MAX*2];
283 sprintf(command, OGG123_STR, filename);
284 file = popen(command, "r");
286 if (!file) return TX_AUDIO_ERR_OGG123;
292 #ifdef USE_BUILTIN_WAV
293 #define min(a,b) ((a) < (b) ? (a) : (b))
294 int tx_audiofile :: load_wav()
303 mem_type=TX_AUDIO_LOAD;
305 if (!init_wav_read(filename, &wav_in))
307 return(TX_AUDIO_ERR_WAV_NOTFOUND);
311 printf("Loading: %s\n", filename);
312 if (parms.verbose) printf("File: %i Bytes Data, %i Bit Depth, %i Hz Samplerate.\n", wav_in.len, wav_in.depth, wav_in.srate);
315 if (wav_in.depth != 16)
317 return(TX_AUDIO_ERR_NOT_16BIT);
320 if (wav_in.chans != 1)
322 return(TX_AUDIO_ERR_NOT_MONO);
326 if (wav_in.srate != 44100)
328 puts("[load_wav] Warning: Wave-File was not recorded at 44.100 Hz!");
330 if (wav_in.blkalign != 2)
332 printf("[load_wav] Warning: Unexpected block alignment: %i.\n", wav_in.blkalign);
337 data = (int16_t *) malloc (memsize);
341 return(TX_AUDIO_ERR_ALLOC);
346 while (wav_in.len>allbytes)
348 bytes = fread(p, 1, min(1024, wav_in.len-allbytes), wav_in.handle);
352 return (TX_AUDIO_ERR_WAV_READ);
355 #ifdef BIG_ENDIAN_MACHINE
356 swapbuffer(p, bytes/sizeof(int16_t));
360 ld_set_progress((float) allbytes/(float)wav_in.len);
362 p+=(ssize_t) bytes/sizeof(int16_t);
365 wav_close(wav_in.handle);
368 no_samples=memsize/sizeof(int16_t);
370 return (TX_AUDIO_SUCCESS);