8372aa713eea257a436b89a63211a7097279ac65
[terminatorX.git] / src / tX_audiofile.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2003  Alexander K├Ânig
4  
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.
9  
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.
14  
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.
18  
19     File: tX_audiofile.cc
20  
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)).
28                  
29     Changes:
30         
31         13 Sept 2002 -  Wrote a seperate loading routine to be used with
32                                 libmad, which is significantly better then piping mpg?1?.
33                                 Rewrote load_piped to use realloc() instead - much easier,
34                                 faster and uses less memory - wish I'd known about realloc()
35                                 when coding load_piped() for the first time ;)
36 */   
37
38
39 #include "tX_audiofile.h"
40
41 #include <string.h>
42 #include <malloc.h>
43 #include "wav_file.h"
44 #include "tX_loaddlg.h"
45 #include "tX_endian.h"
46
47 #ifdef USE_MAD_INPUT
48 #       include <mad.h>
49 #       include <sys/types.h>
50 #       include <unistd.h>
51 #       ifndef _POSIX_MAPPED_FILES
52 #               define _POSIX_MAPPED_FILES
53 #       endif
54 #       include <sys/stat.h>
55 #       include <fcntl.h>
56 #       include <sys/mman.h>
57 #endif
58
59 #ifdef USE_VORBIS_INPUT
60 #       include <vorbis/codec.h>
61 #       include <vorbis/vorbisfile.h>
62 #       include <errno.h>
63 #       include <sys/stat.h>
64 #       include <fcntl.h>
65 #       include <sys/mman.h>
66 #endif
67
68 #ifdef USE_AUDIOFILE_INPUT
69 #       include <audiofile.h>
70 #endif
71
72 tx_audiofile :: tx_audiofile()
73 {
74         mem_type=TX_AUDIO_UNDEFINED;
75         file_type=TX_FILE_UNDEFINED;
76         file=NULL;
77         strcpy(filename,"");
78         mem=NULL;
79         no_samples=0;
80         sample_rate=44100;
81 }
82
83 void tx_audiofile :: figure_file_type()
84 {
85         char *ext;
86         
87         ext=strrchr(filename, (int) '.');
88         
89         if (ext)
90         {
91                 if (strlen(ext) >3)
92                 {
93                         ext++;
94                         if (!strcasecmp("wav", ext)) file_type=TX_FILE_WAV;
95                         else if (!strncasecmp("mp", ext, 2)) file_type=TX_FILE_MPG123;
96                         else if (!strncasecmp("ogg", ext, 2)) file_type=TX_FILE_OGG123;
97                 }
98         }
99 }
100
101 tX_audio_error tx_audiofile :: load(char *p_file_name)
102 {
103         tX_audio_error load_err=TX_AUDIO_ERR_NOT_SUPPORTED;
104         
105         strcpy(filename, p_file_name);
106         
107         ld_set_progress(0);
108                 
109         figure_file_type();
110
111 #ifdef USE_AUDIOFILE_INPUT
112         if ((load_err) && (file_type!=TX_FILE_MPG123) && (file_type!=TX_FILE_OGG123)) {
113                 load_err=load_af();
114         }
115 #endif
116         
117 #ifdef USE_BUILTIN_WAV
118         if ((load_err) && (file_type==TX_FILE_WAV)) {
119                 load_err=load_wav();    
120 //              if (load_err==TX_AUDIO_SUCCESS) return(load_err);
121         }
122 #endif  
123
124 #ifdef USE_MAD_INPUT
125         if ((load_err) && (file_type==TX_FILE_MPG123)) {
126                 load_err=load_mad();
127                 //if (load_err==TX_AUDIO_SUCCESS) return(load_err);
128         }
129 #endif  
130         
131 #ifdef USE_MPG123_INPUT
132         if ((load_err) && (file_type==TX_FILE_MPG123)) {
133                 load_err=load_mpg123();
134                 //return(load_err);
135         }
136 #endif  
137
138 #ifdef USE_VORBIS_INPUT
139         if ((load_err) && (file_type==TX_FILE_OGG123)) {
140                 load_err=load_vorbis();
141                 //if (load_err==TX_AUDIO_SUCCESS) return(load_err);
142         }
143 #endif
144         
145 #ifdef USE_OGG123_INPUT
146         if ((load_err) && (file_type==TX_FILE_OGG123)) {
147                 load_err=load_ogg123();
148                 //return(load_err);
149         }
150 #endif
151
152 #ifdef USE_SOX_INPUT
153         if (load_err) {
154                 load_err=load_sox();
155         }
156 #endif  
157
158         if (!load_err) {
159                 tX_debug("tx_audiofile::load() Set samplerate to %i for file %s.", sample_rate, filename);
160         }
161         return(load_err);
162 }
163
164 tx_audiofile :: ~tx_audiofile() {
165         switch (mem_type) {
166                 case TX_AUDIO_MMAP: break;
167                 case TX_AUDIO_LOAD: {
168                         free(mem);
169                         break;
170                 }
171                 case TX_AUDIO_UNDEFINED: break;
172         }       
173
174         if (file) {
175                 if (mem_type==TX_AUDIO_MMAP) {
176                         // free mmap
177                 }
178         }
179  }
180  
181 #ifdef NEED_PIPED 
182
183 tX_audio_error tx_audiofile :: load_piped()
184 {
185         int16_t *data=NULL;
186         ssize_t allbytes=0;
187         ssize_t prev_bytes;
188         ssize_t bytes=1;
189         unsigned char buffer[SOX_BLOCKSIZE];
190         unsigned char *ptr;
191         
192         /* Irritating the user... */
193         ld_set_progress(0.5);
194         mem_type=TX_AUDIO_LOAD; 
195         
196         while (bytes) {
197                 bytes = fread(buffer, 1, SOX_BLOCKSIZE, file);
198                 
199                 if (bytes>0) {
200                         prev_bytes=allbytes;
201                         allbytes+=bytes;
202                         int16_t *new_data=(int16_t *) realloc(data, allbytes);
203                         //printf("All: %i, Bytes: %i, new: %08x, old: %08x\n", allbytes, bytes, new_data, data);
204                         
205                         if (!new_data) {
206                                 pclose(file); file=NULL;
207                                 if (data) free(data);
208                                 data=NULL;
209                                 return TX_AUDIO_ERR_ALLOC;
210                         }
211                         
212                         data=new_data;
213                         ptr=(unsigned char *) data;
214                         memcpy((void *) &ptr[prev_bytes],(void *) buffer, bytes);
215                 }
216         }
217         
218         pclose(file); file=NULL;
219         
220         if (!allbytes) {
221                 // If we get here we read zero Bytes...
222                 if (data) free(data);
223                 return TX_AUDIO_ERR_PIPE_READ;
224         }
225         
226         no_samples=allbytes/sizeof(int16_t);
227         mem=data;
228         
229         /* Irritating the user just a little more ;)*/
230         ld_set_progress(1.0);
231         
232         return TX_AUDIO_SUCCESS;
233 }
234
235 #endif
236         
237 #ifdef USE_SOX_INPUT
238 tX_audio_error tx_audiofile :: load_sox() {
239         tX_debug("tx_audiofile::load_sox()");
240
241         char command[PATH_MAX*2];
242
243         sprintf(command, SOX_STR, filename);
244         file = popen(command, "r");
245         
246         if (!file) return TX_AUDIO_ERR_SOX;
247         
248         return load_piped();
249         
250 }
251 #endif  
252
253 #ifdef USE_MPG123_INPUT
254 tX_audio_error tx_audiofile :: load_mpg123() {
255         tX_debug("tx_audiofile::load_mpg123()");
256         
257         char command[PATH_MAX*2];
258         
259         sprintf(command, MPG123_STR, filename);
260         file = popen(command, "r");
261         
262         if (!file) return TX_AUDIO_ERR_MPG123;
263         
264         return load_piped();
265 }
266 #endif  
267
268 #ifdef USE_OGG123_INPUT
269 tX_audio_error tx_audiofile :: load_ogg123() {
270         tX_debug("tx_audiofile::load_ogg123()");
271         
272         char command[PATH_MAX*2];
273
274         sprintf(command, OGG123_STR, filename);
275         file = popen(command, "r");
276
277         if (!file) return TX_AUDIO_ERR_OGG123;
278
279         return load_piped();
280 }
281 #endif
282
283 #ifdef USE_BUILTIN_WAV
284 #define min(a,b) ((a) < (b) ? (a) : (b))
285 tX_audio_error tx_audiofile :: load_wav() {
286         tX_debug("tx_audiofile::load_wav()");
287         
288         wav_sig wav_in;
289         int16_t *data;
290         int16_t *p;
291         ssize_t allbytes=0;
292         ssize_t bytes=0;
293
294         mem_type=TX_AUDIO_LOAD;
295         
296         if (!init_wav_read(filename, &wav_in))
297         {
298                 return(TX_AUDIO_ERR_WAV_NOTFOUND);
299         }
300
301         if (wav_in.depth != 16)
302         {
303                 return(TX_AUDIO_ERR_NOT_16BIT);
304         }
305
306         if (wav_in.chans != 1)
307         {
308                 return(TX_AUDIO_ERR_NOT_MONO);
309         }
310
311         sample_rate=wav_in.srate;
312         
313         memsize=wav_in.len;
314         data = (int16_t *) malloc (memsize);
315                 
316         if (!data)
317         {
318                 return(TX_AUDIO_ERR_ALLOC);
319         }
320
321         p=data;
322 #ifdef ENABLE_DEBUG_OUTPUT
323         int output=1;
324         unsigned char *debug_p=(unsigned char *) p;
325 #endif  
326         while (wav_in.len>allbytes)
327         {       
328                 bytes = fread(p, 1, min(1024, wav_in.len-allbytes), wav_in.handle);
329
330 #ifdef ENABLE_DEBUG_OUTPUT
331                 if (output) { tX_debug("tX_audiofile::load_wav() read %i Bytes [%04x %04x %04x %04x %04x %04x ..]", bytes, (unsigned int) p[0],  (unsigned int) p[1], (unsigned int) p[2], (unsigned int) p[3], (unsigned int) p[4], (unsigned int) p[5]); }
332 #endif
333
334                 if (bytes<=0) {
335                         free(data);
336                         return (TX_AUDIO_ERR_WAV_READ);
337                 }
338
339 #ifdef BIG_ENDIAN_MACHINE
340                 swapbuffer(p, bytes/sizeof(int16_t));
341 #       ifdef ENABLE_DEBUG_OUTPUT
342                 if (output) { tX_debug("tX_audiofile::load_wav() swapped %i Bytes [%04x %04x %04x %04x %04x %04x ..]",
343                 bytes, (unsigned int) p[0],  (unsigned int) p[1], (unsigned int) p[2], (unsigned int) p[3], (unsigned int) p[4], (unsigned int) p[5]); }
344 #       endif
345 #endif          
346
347 #ifdef ENABLE_DEBUG_OUTPUT
348                 output=0;
349 #endif
350
351                 allbytes+=bytes;
352                 
353                 ld_set_progress((float) allbytes/(float)wav_in.len);
354                 
355                 p+=(ssize_t) bytes/sizeof(int16_t);
356         }
357         
358         wav_close(wav_in.handle);
359
360         mem=data;
361         no_samples=memsize/sizeof(int16_t);
362         
363         return (TX_AUDIO_SUCCESS);
364 }
365 #endif
366
367 #ifdef USE_MAD_INPUT
368 tX_audio_error tx_audiofile::load_mad() {
369         tX_debug("tx_audiofile::load_mad()");
370         
371         struct stat stat_dat;
372         int fd;
373         int res;
374         void *mp3_file;
375         
376         fd=open(filename, O_RDONLY);
377         if (!fd) return TX_AUDIO_ERR_MAD_OPEN;
378         
379         if (fstat(fd, &stat_dat) == -1 ||
380       stat_dat.st_size == 0) {
381                 return TX_AUDIO_ERR_MAD_STAT;
382         }
383         
384         mp3_file = mmap(0, stat_dat.st_size, PROT_READ, MAP_SHARED, fd, 0);
385         
386         if (mp3_file == MAP_FAILED) {
387                 return TX_AUDIO_ERR_MAD_MMAP;
388         }
389         
390         res=mad_decode((const unsigned char *) mp3_file, stat_dat.st_size);
391         
392         if (res) {
393                 return TX_AUDIO_ERR_MAD_DECODE;
394         }
395         
396         mem_type=TX_AUDIO_LOAD;
397         
398         if (munmap(mp3_file, stat_dat.st_size) == -1) {
399                 return TX_AUDIO_ERR_MAD_MUNMAP;
400         }
401         
402         return TX_AUDIO_SUCCESS;
403 }
404
405 #define TX_MAD_BLOCKSIZE 8096
406
407 typedef struct {
408         const unsigned char *start;
409         const unsigned char *end;
410         const unsigned char *last_frame;
411         bool first_call;
412         ssize_t size;
413         int16_t *target_buffer;
414         unsigned int target_samples;
415         unsigned int current_sample;
416         unsigned int sample_rate;
417         unsigned int lost_sync_counter;
418 } tX_mad_buffer;
419
420 const unsigned char *last_current=NULL;
421
422 static enum mad_flow tX_mad_input(void *data, struct mad_stream *stream) {
423         tX_mad_buffer *buffer = (tX_mad_buffer *) data;
424         ssize_t bs;
425         unsigned int pos;
426
427         if (buffer->first_call) {
428                 bs=min(TX_MAD_BLOCKSIZE, buffer->size);
429                 mad_stream_buffer(stream, buffer->start, bs);
430                 buffer->first_call=false;
431                 return MAD_FLOW_CONTINUE;
432         } else {
433                 if (!stream->next_frame) return MAD_FLOW_STOP;
434                 
435                 pos=stream->next_frame-buffer->start;
436                 bs=min(TX_MAD_BLOCKSIZE, buffer->size-pos);
437                 //tX_debug("last: %08x, new %08x, bs: %i, pos: %i",  buffer->last_frame, stream->next_frame, bs, pos);
438                 
439                 mad_stream_buffer(stream, stream->next_frame, bs);
440                 if (stream->next_frame==buffer->last_frame) {
441                         //tX_debug("tX_mad_input(): No new frame? Stopping.");
442                         return MAD_FLOW_STOP;
443                 }
444                 ld_set_progress((float) pos/(float) buffer->size);
445                 buffer->last_frame=stream->next_frame;
446
447                 return MAD_FLOW_CONTINUE;
448         }
449 }
450
451 static enum mad_flow tX_mad_error(void *data, struct mad_stream *stream, struct mad_frame *frame) {
452         tX_mad_buffer *buffer = (tX_mad_buffer *) data;
453         if (MAD_RECOVERABLE(stream->error)) {
454                 if ((stream->error==MAD_ERROR_LOSTSYNC) && (buffer->lost_sync_counter<3)) {
455                         /* Ignore at least two sync errors to not annoy people
456                            about ID3 tags.
457                         */
458                         buffer->lost_sync_counter++;
459                         return MAD_FLOW_CONTINUE;
460                 }
461                 tX_warning("mad reported stream error (%i) '%s'.", stream->error, mad_stream_errorstr(stream));
462                 return MAD_FLOW_CONTINUE;
463         }
464         tX_error("mad reported fatal stream error (%i) '%s'.", stream->error, mad_stream_errorstr(stream));
465         return MAD_FLOW_STOP;
466 }
467
468 /* From minimad.c of mad */
469 static inline signed int scale(mad_fixed_t sample) {
470 //#ifdef BIG_ENDIAN_MACHINE
471 //      swap32_inline(&sample);
472 //#endif
473   /* round */
474   sample += (1L << (MAD_F_FRACBITS - 16));
475
476   /* clip */
477   if (sample >= MAD_F_ONE)
478     sample = MAD_F_ONE - 1;
479   else if (sample < -MAD_F_ONE)
480     sample = -MAD_F_ONE;
481
482   /* quantize */
483   return sample >> (MAD_F_FRACBITS + 1 - 16);
484 }
485
486 static enum mad_flow tX_mad_output(void *data, struct mad_header const *header, struct mad_pcm *pcm) {
487         tX_mad_buffer *buffer=(tX_mad_buffer *) data;
488         unsigned int nchannels, nsamples;
489         mad_fixed_t const *left_ch, *right_ch;  
490
491         nchannels = pcm->channels;
492         nsamples  = pcm->length;
493         left_ch   = pcm->samples[0];
494         right_ch  = pcm->samples[1];
495         buffer->sample_rate = pcm->samplerate;
496         
497         buffer->target_samples+=nsamples;
498
499         buffer->target_buffer=(int16_t *) realloc(buffer->target_buffer, buffer->target_samples<<1);
500         if (!buffer->target_buffer) { 
501                         tX_error("tX_mad_output(): Failed allocating sample memory!\n");
502                         return MAD_FLOW_STOP;
503         }
504                 
505         while (nsamples--) {
506                 signed int sample;
507
508                 if (nchannels==1) {
509                         sample=scale(*left_ch++);
510                 } else {
511                         double sample_l=(double) (*left_ch++);
512                         double sample_r=(double) (*right_ch++); 
513                         double res=(sample_l+sample_r)/2.0;
514                         mad_fixed_t mad_res=(mad_fixed_t) res;
515                         
516                         sample=scale(mad_res);
517                 }
518                 
519                 buffer->target_buffer[buffer->current_sample]=sample;
520                 buffer->current_sample++;
521         }
522
523         return MAD_FLOW_CONTINUE;
524 }
525
526 int tx_audiofile::mad_decode(unsigned char const *start, unsigned long length) {
527         tX_mad_buffer buffer;
528         struct mad_decoder decoder;
529         int result;
530
531         buffer.start  = start;
532         buffer.end = &start[length];
533         buffer.last_frame = NULL;
534         buffer.size = length;
535         buffer.target_buffer = NULL;
536         buffer.target_samples = 0;
537         buffer.current_sample = 0;
538         buffer.first_call=true;
539         buffer.sample_rate=0;
540         buffer.lost_sync_counter=0;
541
542         tX_debug("tx_audiofile::mad_decode() - start %08x, length %i", buffer.start, buffer.size);
543         /* configure input, output, and error functions */
544
545         mad_decoder_init(&decoder, &buffer, tX_mad_input, NULL, NULL, tX_mad_output, tX_mad_error, NULL);
546         result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
547
548         if (!result) {
549                 this->mem=buffer.target_buffer;
550                 this->no_samples=buffer.target_samples;
551         } else {
552                 if (buffer.target_buffer) free(buffer.target_buffer);
553         }
554         
555         /* release the decoder */
556         mad_decoder_finish(&decoder);  
557
558         sample_rate=buffer.sample_rate;
559   return result;
560 }
561
562 #endif
563
564 /* AARG - OGG loading is not threadsafe !*/
565 size_t tX_ogg_file_size;
566 long tX_ogg_file_read;
567
568 #ifdef USE_VORBIS_INPUT
569 typedef struct {
570   size_t (*read_func) (void *, size_t, size_t, FILE *);
571   int  (*seek_func) (void *, long, int);
572   int (*close_func) (FILE *);
573   long (*tell_func) (FILE *);
574 } tX_ov_callbacks;
575
576 int ogg_seek(void *ptr, long offset, int whence) {
577         /* ogg shall not seek ! */
578         return -1;
579         errno=EBADF;
580 }
581
582 size_t ogg_read(void  *ptr, size_t size, size_t nmemb, FILE *stream) {
583         size_t ret_val;
584         ret_val=fread(ptr, size, nmemb, stream);
585         if (ret_val>0) {
586                 tX_ogg_file_read+=ret_val*size;
587                 ld_set_progress((double) tX_ogg_file_read/(double) tX_ogg_file_size);   
588         }
589         return ret_val;
590 }
591
592 #define VORBIS_BUFF_SIZE 4096 /*recommended*/
593
594 tX_audio_error tx_audiofile::load_vorbis() {
595         tX_debug("tx_audiofile::load_vorbis()");
596         
597         /*  VORBIS Callbacks */
598         ov_callbacks org_callbacks;
599         /* evil casting - to make g++ shut up */
600         tX_ov_callbacks *callbacks=(tX_ov_callbacks *) &org_callbacks;
601         
602         /* buffer */
603         char pcmout[VORBIS_BUFF_SIZE];
604         OggVorbis_File vf;
605         bool eof=false;
606         int current_section=0;
607         unsigned int i;
608         struct stat stat_dat;
609                 
610         callbacks->read_func=ogg_read;
611         callbacks->seek_func=ogg_seek;
612         callbacks->close_func=fclose;
613         callbacks->tell_func=ftell;
614         
615         file=fopen(filename, "r");
616         if (!file) {
617                 return TX_AUDIO_ERR_WAV_NOTFOUND;               
618         }
619         
620         if (fstat(fileno(file), &stat_dat)  == -1 || stat_dat.st_size == 0) {
621                 return TX_AUDIO_ERR_MAD_STAT;
622         }
623         
624         tX_ogg_file_size=stat_dat.st_size;
625         tX_ogg_file_read=0;
626         
627         int res=ov_open_callbacks((void *) file, &vf, NULL, 0, org_callbacks);
628         if (res<0) {
629                 fclose(file); 
630                 file=NULL;
631                 return TX_AUDIO_ERR_VORBIS_OPEN;                
632         }
633         
634         vorbis_info *vi=ov_info(&vf,-1);
635         sample_rate=vi->rate;
636
637         unsigned int channels=vi->channels;     
638         unsigned int samples_read=0;
639         unsigned int mono_samples;
640         int16_t* data=NULL;
641         size_t bytes=0;
642         
643         while((!eof) && (!current_section)) {
644 #ifdef BIG_ENDIAN_MACHINE
645 #       define ENDIANP 1
646 #else
647 #       define ENDIANP 0                
648 #endif
649                 long ret=ov_read(&vf,pcmout,VORBIS_BUFF_SIZE,ENDIANP,2,1,&current_section);
650                 if (ret == 0) {
651                         eof=true;
652                 } else if (ret < 0) {
653                   /* ignore stream errors */
654                 } else {
655                         int16_t *new_data;
656                         bytes+=ret;
657                         new_data=(int16_t *) realloc(data, bytes/channels);
658                         if (!new_data) {
659                                 if (data) free(data);
660                                 return TX_AUDIO_ERR_ALLOC;\r
661                         }
662                         
663                         data=new_data;
664                         int16_t *src=(int16_t *) &pcmout;
665                         
666                         switch (channels) {
667                                 case 1:
668                                         mono_samples=ret/2;
669                                         for (i=0; i<mono_samples; i++) {
670                                                 data[samples_read+i]=src[i];
671                                         }
672                                         break;
673                                         
674                                 case 2:
675                                         mono_samples=ret/4;
676                                         for (i=0; i<mono_samples; i++) {
677                                                 double l_value, r_value;
678                                                 l_value=src[i*2];
679                                                 r_value=src[i*2+1];
680                                                 data[samples_read+i]=(int16_t) ((l_value+r_value)/2.0);
681                                         }
682                                         break;
683                                         
684                                 default:
685                                         mono_samples=(ret/2)/channels;
686                                         for (i=0; i<mono_samples; i++) {
687                                                 double value=0.0;
688                                 
689                                                 for (unsigned int c=0; c<channels; c++) {
690                                                         value+=(double) src[i*channels+c];
691                                                 }
692                                                 value/=(double) channels;
693                                                 data[samples_read+i]=(int16_t) value;
694                                         }               
695                         }
696                         samples_read+=mono_samples;
697                 }
698     }
699         
700         ov_clear(&vf);
701         
702         mem=(int16_t *) data;
703         no_samples=samples_read;
704         
705         if (no_samples==0) {
706                 if (mem) free(mem);
707                 mem=NULL;
708                 return TX_AUDIO_ERR_VORBIS_NODATA;
709         }
710         
711         return TX_AUDIO_SUCCESS;
712 }
713 #endif
714
715 #ifdef USE_AUDIOFILE_INPUT
716 #define TX_AF_SAMPLES_PER_BLOCK 2048
717
718 tX_audio_error tx_audiofile::load_af() {
719         tX_debug("tx_audiofile::load_af()");
720         
721         AFfilehandle af_file;
722         AFframecount    all_frames, frames_read=0, current_frames=1;
723         int16_t *data=NULL;
724         
725         af_file = afOpenFile(filename, "r", NULL);
726         if (af_file==AF_NULL_FILEHANDLE) {
727                 return TX_AUDIO_ERR_AF_OPEN;
728         }
729         
730         all_frames=afGetFrameCount(af_file, AF_DEFAULT_TRACK);
731         sample_rate=(unsigned int) afGetRate(af_file, AF_DEFAULT_TRACK);
732         afSetVirtualChannels(af_file, AF_DEFAULT_TRACK, 1);
733         afSetVirtualSampleFormat(af_file, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); // 2 == 16 Bit?
734 #ifdef BIG_ENDIAN_MACHINE
735         afSetVirtualByteOrder(af_file, AF_DEFAULT_TRACK, AF_BYTEORDER_BIGENDIAN);
736 #else
737         afSetVirtualByteOrder(af_file, AF_DEFAULT_TRACK, AF_BYTEORDER_LITTLEENDIAN);
738 #endif
739         
740         while (current_frames) {
741                 int16_t *new_data;
742                 
743                 new_data=(int16_t*) realloc(data, (frames_read+TX_AF_SAMPLES_PER_BLOCK)*2);
744                 if (!new_data) {
745                         if (data) free(data);
746                         afCloseFile(af_file);
747                         return TX_AUDIO_ERR_ALLOC;
748                 }
749                 data=new_data;
750                 current_frames=afReadFrames(af_file,AF_DEFAULT_TRACK,(void *) &data[frames_read],TX_AF_SAMPLES_PER_BLOCK);
751                 frames_read+=current_frames;
752                 ld_set_progress(((double) frames_read)/((double) all_frames));
753         }
754         afCloseFile(af_file);
755         
756         if (!frames_read) {
757                 if (data) free(data);
758                 return TX_AUDIO_ERR_AF_NODATA;
759         }
760         
761         /* shorten to the actually read size of samples */
762         if (!realloc(data, frames_read*2)) {
763                         if (data) free(data);
764                         return TX_AUDIO_ERR_ALLOC;
765         }
766         
767         mem=data;
768         no_samples=frames_read;
769         
770         return TX_AUDIO_SUCCESS;
771 }
772 #endif