~ubuntu-branches/ubuntu/dapper/terminatorx/dapper

« back to all changes in this revision

Viewing changes to src/tX_audiofile.cc

  • Committer: Bazaar Package Importer
  • Author(s): Mike Furr
  • Date: 2004-04-26 21:20:09 UTC
  • Revision ID: james.westby@ubuntu.com-20040426212009-acjw8flkt05j945f
Tags: upstream-3.81
Import upstream version 3.81

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#define min(a,b) ((a) < (b) ? (a) : (b))
 
73
 
 
74
tx_audiofile :: tx_audiofile()
 
75
{
 
76
        mem_type=TX_AUDIO_UNDEFINED;
 
77
        file_type=TX_FILE_UNDEFINED;
 
78
        file=NULL;
 
79
        strcpy(filename,"");
 
80
        mem=NULL;
 
81
        no_samples=0;
 
82
        sample_rate=44100;
 
83
}
 
84
 
 
85
void tx_audiofile :: figure_file_type()
 
86
{
 
87
        char *ext;
 
88
        
 
89
        ext=strrchr(filename, (int) '.');
 
90
        
 
91
        if (ext) {
 
92
                if (strlen(ext) >3) {
 
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
tX_audio_error tx_audiofile :: load_wav() {
 
276
        tX_debug("tx_audiofile::load_wav()");
 
277
        
 
278
        wav_sig wav_in;
 
279
        int16_t *data;
 
280
        int16_t *p;
 
281
        ssize_t allbytes=0;
 
282
        ssize_t bytes=0;
 
283
 
 
284
        mem_type=TX_AUDIO_LOAD;
 
285
        
 
286
        if (!init_wav_read(filename, &wav_in))
 
287
        {
 
288
                return(TX_AUDIO_ERR_WAV_NOTFOUND);
 
289
        }
 
290
 
 
291
        if (wav_in.depth != 16)
 
292
        {
 
293
                return(TX_AUDIO_ERR_NOT_16BIT);
 
294
        }
 
295
 
 
296
        if (wav_in.chans != 1)
 
297
        {
 
298
                return(TX_AUDIO_ERR_NOT_MONO);
 
299
        }
 
300
 
 
301
        sample_rate=wav_in.srate;
 
302
        
 
303
        memsize=wav_in.len;
 
304
        data = (int16_t *) malloc (memsize);
 
305
                
 
306
        if (!data)
 
307
        {
 
308
                return(TX_AUDIO_ERR_ALLOC);
 
309
        }
 
310
 
 
311
        p=data;
 
312
#ifdef ENABLE_DEBUG_OUTPUT
 
313
        int output=1;
 
314
#endif  
 
315
        while (wav_in.len>allbytes)
 
316
        {       
 
317
                bytes = fread(p, 1, min(1024, wav_in.len-allbytes), wav_in.handle);
 
318
 
 
319
#ifdef ENABLE_DEBUG_OUTPUT
 
320
                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]); }
 
321
#endif
 
322
 
 
323
                if (bytes<=0) {
 
324
                        free(data);
 
325
                        return (TX_AUDIO_ERR_WAV_READ);
 
326
                }
 
327
 
 
328
#ifdef BIG_ENDIAN_MACHINE
 
329
                swapbuffer(p, bytes/sizeof(int16_t));
 
330
#       ifdef ENABLE_DEBUG_OUTPUT
 
331
                if (output) { tX_debug("tX_audiofile::load_wav() swapped %i Bytes [%04x %04x %04x %04x %04x %04x ..]",
 
332
                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]); }
 
333
#       endif
 
334
#endif          
 
335
 
 
336
#ifdef ENABLE_DEBUG_OUTPUT
 
337
                output=0;
 
338
#endif
 
339
 
 
340
                allbytes+=bytes;
 
341
                
 
342
                ld_set_progress((float) allbytes/(float)wav_in.len);
 
343
                
 
344
                p+=(ssize_t) bytes/sizeof(int16_t);
 
345
        }
 
346
        
 
347
        wav_close(wav_in.handle);
 
348
 
 
349
        mem=data;
 
350
        no_samples=memsize/sizeof(int16_t);
 
351
        
 
352
        return (TX_AUDIO_SUCCESS);
 
353
}
 
354
#endif
 
355
 
 
356
#ifdef USE_MAD_INPUT
 
357
tX_audio_error tx_audiofile::load_mad() {
 
358
        tX_debug("tx_audiofile::load_mad()");
 
359
        
 
360
        struct stat stat_dat;
 
361
        int fd;
 
362
        int res;
 
363
        void *mp3_file;
 
364
        
 
365
        fd=open(filename, O_RDONLY);
 
366
        if (!fd) return TX_AUDIO_ERR_MAD_OPEN;
 
367
        
 
368
        if (fstat(fd, &stat_dat) == -1 ||
 
369
      stat_dat.st_size == 0) {
 
370
                return TX_AUDIO_ERR_MAD_STAT;
 
371
        }
 
372
        
 
373
        mp3_file = mmap(0, stat_dat.st_size, PROT_READ, MAP_SHARED, fd, 0);
 
374
        
 
375
        if (mp3_file == MAP_FAILED) {
 
376
                return TX_AUDIO_ERR_MAD_MMAP;
 
377
        }
 
378
        
 
379
        res=mad_decode((const unsigned char *) mp3_file, stat_dat.st_size);
 
380
        
 
381
        if (res) {
 
382
                return TX_AUDIO_ERR_MAD_DECODE;
 
383
        }
 
384
        
 
385
        mem_type=TX_AUDIO_LOAD;
 
386
        
 
387
        if (munmap(mp3_file, stat_dat.st_size) == -1) {
 
388
                return TX_AUDIO_ERR_MAD_MUNMAP;
 
389
        }
 
390
        
 
391
        return TX_AUDIO_SUCCESS;
 
392
}
 
393
 
 
394
#define TX_MAD_BLOCKSIZE 8096
 
395
 
 
396
typedef struct {
 
397
        const unsigned char *start;
 
398
        const unsigned char *end;
 
399
        const unsigned char *last_frame;
 
400
        bool first_call;
 
401
        ssize_t size;
 
402
        int16_t *target_buffer;
 
403
        unsigned int target_samples;
 
404
        unsigned int current_sample;
 
405
        unsigned int sample_rate;
 
406
        unsigned int lost_sync_counter;
 
407
} tX_mad_buffer;
 
408
 
 
409
const unsigned char *last_current=NULL;
 
410
 
 
411
static enum mad_flow tX_mad_input(void *data, struct mad_stream *stream) {
 
412
        tX_mad_buffer *buffer = (tX_mad_buffer *) data;
 
413
        ssize_t bs;
 
414
        unsigned int pos;
 
415
 
 
416
        if (buffer->first_call) {
 
417
                bs=min(TX_MAD_BLOCKSIZE, buffer->size);
 
418
                mad_stream_buffer(stream, buffer->start, bs);
 
419
                buffer->first_call=false;
 
420
                return MAD_FLOW_CONTINUE;
 
421
        } else {
 
422
                if (!stream->next_frame) return MAD_FLOW_STOP;
 
423
                
 
424
                pos=stream->next_frame-buffer->start;
 
425
                bs=min(TX_MAD_BLOCKSIZE, buffer->size-pos);
 
426
                //tX_debug("last: %08x, new %08x, bs: %i, pos: %i",  buffer->last_frame, stream->next_frame, bs, pos);
 
427
                
 
428
                mad_stream_buffer(stream, stream->next_frame, bs);
 
429
                if (stream->next_frame==buffer->last_frame) {
 
430
                        //tX_debug("tX_mad_input(): No new frame? Stopping.");
 
431
                        return MAD_FLOW_STOP;
 
432
                }
 
433
                ld_set_progress((float) pos/(float) buffer->size);
 
434
                buffer->last_frame=stream->next_frame;
 
435
 
 
436
                return MAD_FLOW_CONTINUE;
 
437
        }
 
438
}
 
439
 
 
440
static enum mad_flow tX_mad_error(void *data, struct mad_stream *stream, struct mad_frame *frame) {
 
441
        tX_mad_buffer *buffer = (tX_mad_buffer *) data;
 
442
        if (MAD_RECOVERABLE(stream->error)) {
 
443
                if ((stream->error==MAD_ERROR_LOSTSYNC) && (buffer->lost_sync_counter<3)) {
 
444
                        /* Ignore at least two sync errors to not annoy people
 
445
                           about ID3 tags.
 
446
                        */
 
447
                        buffer->lost_sync_counter++;
 
448
                        return MAD_FLOW_CONTINUE;
 
449
                }
 
450
                tX_warning("mad reported stream error (%i) '%s'.", stream->error, mad_stream_errorstr(stream));
 
451
                return MAD_FLOW_CONTINUE;
 
452
        }
 
453
        tX_error("mad reported fatal stream error (%i) '%s'.", stream->error, mad_stream_errorstr(stream));
 
454
        return MAD_FLOW_STOP;
 
455
}
 
456
 
 
457
/* From minimad.c of mad */
 
458
static inline signed int scale(mad_fixed_t sample) {
 
459
//#ifdef BIG_ENDIAN_MACHINE
 
460
//      swap32_inline(&sample);
 
461
//#endif
 
462
  /* round */
 
463
  sample += (1L << (MAD_F_FRACBITS - 16));
 
464
 
 
465
  /* clip */
 
466
  if (sample >= MAD_F_ONE)
 
467
    sample = MAD_F_ONE - 1;
 
468
  else if (sample < -MAD_F_ONE)
 
469
    sample = -MAD_F_ONE;
 
470
 
 
471
  /* quantize */
 
472
  return sample >> (MAD_F_FRACBITS + 1 - 16);
 
473
}
 
474
 
 
475
static enum mad_flow tX_mad_output(void *data, struct mad_header const *header, struct mad_pcm *pcm) {
 
476
        tX_mad_buffer *buffer=(tX_mad_buffer *) data;
 
477
        unsigned int nchannels, nsamples;
 
478
        mad_fixed_t const *left_ch, *right_ch;  
 
479
 
 
480
        nchannels = pcm->channels;
 
481
        nsamples  = pcm->length;
 
482
        left_ch   = pcm->samples[0];
 
483
        right_ch  = pcm->samples[1];
 
484
        buffer->sample_rate = pcm->samplerate;
 
485
        
 
486
        buffer->target_samples+=nsamples;
 
487
 
 
488
        buffer->target_buffer=(int16_t *) realloc(buffer->target_buffer, buffer->target_samples<<1);
 
489
        if (!buffer->target_buffer) { 
 
490
                        tX_error("tX_mad_output(): Failed allocating sample memory!\n");
 
491
                        return MAD_FLOW_STOP;
 
492
        }
 
493
                
 
494
        while (nsamples--) {
 
495
                signed int sample;
 
496
 
 
497
                if (nchannels==1) {
 
498
                        sample=scale(*left_ch++);
 
499
                } else {
 
500
                        double sample_l=(double) (*left_ch++);
 
501
                        double sample_r=(double) (*right_ch++); 
 
502
                        double res=(sample_l+sample_r)/2.0;
 
503
                        mad_fixed_t mad_res=(mad_fixed_t) res;
 
504
                        
 
505
                        sample=scale(mad_res);
 
506
                }
 
507
                
 
508
                buffer->target_buffer[buffer->current_sample]=sample;
 
509
                buffer->current_sample++;
 
510
        }
 
511
 
 
512
        return MAD_FLOW_CONTINUE;
 
513
}
 
514
 
 
515
int tx_audiofile::mad_decode(unsigned char const *start, unsigned long length) {
 
516
        tX_mad_buffer buffer;
 
517
        struct mad_decoder decoder;
 
518
        int result;
 
519
 
 
520
        buffer.start  = start;
 
521
        buffer.end = &start[length];
 
522
        buffer.last_frame = NULL;
 
523
        buffer.size = length;
 
524
        buffer.target_buffer = NULL;
 
525
        buffer.target_samples = 0;
 
526
        buffer.current_sample = 0;
 
527
        buffer.first_call=true;
 
528
        buffer.sample_rate=0;
 
529
        buffer.lost_sync_counter=0;
 
530
 
 
531
        tX_debug("tx_audiofile::mad_decode() - start %08x, length %i", (int) buffer.start, buffer.size);
 
532
        /* configure input, output, and error functions */
 
533
 
 
534
        mad_decoder_init(&decoder, &buffer, tX_mad_input, NULL, NULL, tX_mad_output, tX_mad_error, NULL);
 
535
        result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
 
536
 
 
537
        if (!result) {
 
538
                this->mem=buffer.target_buffer;
 
539
                this->no_samples=buffer.target_samples;
 
540
        } else {
 
541
                if (buffer.target_buffer) free(buffer.target_buffer);
 
542
        }
 
543
        
 
544
        /* release the decoder */
 
545
        mad_decoder_finish(&decoder);  
 
546
 
 
547
        sample_rate=buffer.sample_rate;
 
548
  return result;
 
549
}
 
550
 
 
551
#endif
 
552
 
 
553
/* AARG - OGG loading is not threadsafe !*/
 
554
size_t tX_ogg_file_size;
 
555
long tX_ogg_file_read;
 
556
 
 
557
#ifdef USE_VORBIS_INPUT
 
558
typedef struct {
 
559
  size_t (*read_func) (void *, size_t, size_t, FILE *);
 
560
  int  (*seek_func) (void *, long, int);
 
561
  int (*close_func) (FILE *);
 
562
  long (*tell_func) (FILE *);
 
563
} tX_ov_callbacks;
 
564
 
 
565
int ogg_seek(void *ptr, long offset, int whence) {
 
566
        /* ogg shall not seek ! */
 
567
        return -1;
 
568
        errno=EBADF;
 
569
}
 
570
 
 
571
size_t ogg_read(void  *ptr, size_t size, size_t nmemb, FILE *stream) {
 
572
        size_t ret_val;
 
573
        ret_val=fread(ptr, size, nmemb, stream);
 
574
        if (ret_val>0) {
 
575
                tX_ogg_file_read+=ret_val*size;
 
576
                ld_set_progress((double) tX_ogg_file_read/(double) tX_ogg_file_size);   
 
577
        }
 
578
        return ret_val;
 
579
}
 
580
 
 
581
#define VORBIS_BUFF_SIZE 4096 /*recommended*/
 
582
 
 
583
tX_audio_error tx_audiofile::load_vorbis() {
 
584
        tX_debug("tx_audiofile::load_vorbis()");
 
585
        
 
586
        /*  VORBIS Callbacks */
 
587
        ov_callbacks org_callbacks;
 
588
        /* evil casting - to make g++ shut up */
 
589
        tX_ov_callbacks *callbacks=(tX_ov_callbacks *) &org_callbacks;
 
590
        
 
591
        /* buffer */
 
592
        char pcmout[VORBIS_BUFF_SIZE];
 
593
        OggVorbis_File vf;
 
594
        bool eof=false;
 
595
        int current_section=0;
 
596
        unsigned int i;
 
597
        struct stat stat_dat;
 
598
                
 
599
        callbacks->read_func=ogg_read;
 
600
        callbacks->seek_func=ogg_seek;
 
601
        callbacks->close_func=fclose;
 
602
        callbacks->tell_func=ftell;
 
603
        
 
604
        file=fopen(filename, "r");
 
605
        if (!file) {
 
606
                return TX_AUDIO_ERR_WAV_NOTFOUND;               
 
607
        }
 
608
        
 
609
        if (fstat(fileno(file), &stat_dat)  == -1 || stat_dat.st_size == 0) {
 
610
                return TX_AUDIO_ERR_MAD_STAT;
 
611
        }
 
612
        
 
613
        tX_ogg_file_size=stat_dat.st_size;
 
614
        tX_ogg_file_read=0;
 
615
        
 
616
        int res=ov_open_callbacks((void *) file, &vf, NULL, 0, org_callbacks);
 
617
        if (res<0) {
 
618
                fclose(file); 
 
619
                file=NULL;
 
620
                return TX_AUDIO_ERR_VORBIS_OPEN;                
 
621
        }
 
622
        
 
623
        vorbis_info *vi=ov_info(&vf,-1);
 
624
        sample_rate=vi->rate;
 
625
 
 
626
        unsigned int channels=vi->channels;     
 
627
        unsigned int samples_read=0;
 
628
        unsigned int mono_samples;
 
629
        int16_t* data=NULL;
 
630
        size_t bytes=0;
 
631
        
 
632
        while((!eof) && (!current_section)) {
 
633
#ifdef BIG_ENDIAN_MACHINE
 
634
#       define ENDIANP 1
 
635
#else
 
636
#       define ENDIANP 0                
 
637
#endif
 
638
                long ret=ov_read(&vf,pcmout,VORBIS_BUFF_SIZE,ENDIANP,2,1,&current_section);
 
639
                if (ret == 0) {
 
640
                        eof=true;
 
641
                } else if (ret < 0) {
 
642
                  /* ignore stream errors */
 
643
                } else {
 
644
                        int16_t *new_data;
 
645
                        bytes+=ret;
 
646
                        new_data=(int16_t *) realloc(data, bytes/channels);
 
647
                        if (!new_data) {
 
648
                                if (data) free(data);
 
649
                                return TX_AUDIO_ERR_ALLOC;
 
650
                        }
 
651
                        
 
652
                        data=new_data;
 
653
                        int16_t *src=(int16_t *) &pcmout;
 
654
                        
 
655
                        switch (channels) {
 
656
                                case 1:
 
657
                                        mono_samples=ret/2;
 
658
                                        for (i=0; i<mono_samples; i++) {
 
659
                                                data[samples_read+i]=src[i];
 
660
                                        }
 
661
                                        break;
 
662
                                        
 
663
                                case 2:
 
664
                                        mono_samples=ret/4;
 
665
                                        for (i=0; i<mono_samples; i++) {
 
666
                                                double l_value, r_value;
 
667
                                                l_value=src[i*2];
 
668
                                                r_value=src[i*2+1];
 
669
                                                data[samples_read+i]=(int16_t) ((l_value+r_value)/2.0);
 
670
                                        }
 
671
                                        break;
 
672
                                        
 
673
                                default:
 
674
                                        mono_samples=(ret/2)/channels;
 
675
                                        for (i=0; i<mono_samples; i++) {
 
676
                                                double value=0.0;
 
677
                                
 
678
                                                for (unsigned int c=0; c<channels; c++) {
 
679
                                                        value+=(double) src[i*channels+c];
 
680
                                                }
 
681
                                                value/=(double) channels;
 
682
                                                data[samples_read+i]=(int16_t) value;
 
683
                                        }               
 
684
                        }
 
685
                        samples_read+=mono_samples;
 
686
                }
 
687
    }
 
688
        
 
689
        ov_clear(&vf);
 
690
        
 
691
        mem=(int16_t *) data;
 
692
        no_samples=samples_read;
 
693
        
 
694
        if (no_samples==0) {
 
695
                if (mem) free(mem);
 
696
                mem=NULL;
 
697
                return TX_AUDIO_ERR_VORBIS_NODATA;
 
698
        }
 
699
        
 
700
        return TX_AUDIO_SUCCESS;
 
701
}
 
702
#endif
 
703
 
 
704
#ifdef USE_AUDIOFILE_INPUT
 
705
#define TX_AF_SAMPLES_PER_BLOCK 2048
 
706
 
 
707
tX_audio_error tx_audiofile::load_af() {
 
708
        tX_debug("tx_audiofile::load_af()");
 
709
        
 
710
        AFfilehandle af_file;
 
711
        AFframecount    all_frames, frames_read=0, current_frames=1;
 
712
        int16_t *data=NULL;
 
713
        
 
714
        af_file = afOpenFile(filename, "r", NULL);
 
715
        if (af_file==AF_NULL_FILEHANDLE) {
 
716
                return TX_AUDIO_ERR_AF_OPEN;
 
717
        }
 
718
        
 
719
        all_frames=afGetFrameCount(af_file, AF_DEFAULT_TRACK);
 
720
        sample_rate=(unsigned int) afGetRate(af_file, AF_DEFAULT_TRACK);
 
721
        afSetVirtualChannels(af_file, AF_DEFAULT_TRACK, 1);
 
722
        afSetVirtualSampleFormat(af_file, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); // 2 == 16 Bit?
 
723
#ifdef BIG_ENDIAN_MACHINE
 
724
        afSetVirtualByteOrder(af_file, AF_DEFAULT_TRACK, AF_BYTEORDER_BIGENDIAN);
 
725
#else
 
726
        afSetVirtualByteOrder(af_file, AF_DEFAULT_TRACK, AF_BYTEORDER_LITTLEENDIAN);
 
727
#endif
 
728
        
 
729
        while (current_frames) {
 
730
                int16_t *new_data;
 
731
                
 
732
                new_data=(int16_t*) realloc(data, (frames_read+TX_AF_SAMPLES_PER_BLOCK)*2);
 
733
                if (!new_data) {
 
734
                        if (data) free(data);
 
735
                        afCloseFile(af_file);
 
736
                        return TX_AUDIO_ERR_ALLOC;
 
737
                }
 
738
                data=new_data;
 
739
                current_frames=afReadFrames(af_file,AF_DEFAULT_TRACK,(void *) &data[frames_read],TX_AF_SAMPLES_PER_BLOCK);
 
740
                frames_read+=current_frames;
 
741
                ld_set_progress(((double) frames_read)/((double) all_frames));
 
742
        }
 
743
        afCloseFile(af_file);
 
744
        
 
745
        if (!frames_read) {
 
746
                if (data) free(data);
 
747
                return TX_AUDIO_ERR_AF_NODATA;
 
748
        }
 
749
        
 
750
        /* shorten to the actually read size of samples */
 
751
        if (!realloc(data, frames_read*2)) {
 
752
                        if (data) free(data);
 
753
                        return TX_AUDIO_ERR_ALLOC;
 
754
        }
 
755
        
 
756
        mem=data;
 
757
        no_samples=frames_read;
 
758
        
 
759
        return TX_AUDIO_SUCCESS;
 
760
}
 
761
#endif