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