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