1
/***************************************************************************
2
soundsource.cpp - description
4
begin : Wed Feb 20 2002
5
copyright : (C) 2002 by Tue and Ken Haste Andersen
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
18
#include "soundsource.h"
21
SoundSource is a Uber-class for the reading and decoding of audio-files.
22
Each class must have the following member functions:
23
initializer with a filename
28
SoundSource::SoundSource() {}
29
SoundSource::~SoundSource() {}
31
Class for reading files using libaudiofile
33
AFlibfile::AFlibfile(const char* filename) {
34
fh = afOpenFile(filename,"r",0);
35
if (fh == AF_NULL_FILEHANDLE) {
36
cout << "Error opening file.\n";
40
filelength = 2*afGetFrameCount(fh,AF_DEFAULT_TRACK);
43
AFlibfile::~AFlibfile() {
47
long AFlibfile::seek(long filepos) {
48
afSeekFrame(fh, AF_DEFAULT_TRACK, (AFframecount) (filepos/channels));
52
read <size> samples into <destination>, and return the number of
53
samples actually read.
55
unsigned AFlibfile::read(unsigned long size, const SAMPLE* destination) {
56
return afReadFrames(fh,AF_DEFAULT_TRACK, (SAMPLE *)destination
57
,size/channels)*channels;
60
Return the length of the file in samples.
62
long unsigned AFlibfile::length() {
67
Reading and decoding of mp3-files:
69
mp3file::mp3file(const char* filename) {
71
file = fopen(filename,"r");
73
cout << "Open of " << filename << " failed\n" << flush;
76
// Read in the whole file into inputbuf:
78
stat(filename, &filestat);
79
mp3filelength = filestat.st_size;
80
inputbuf_len = mp3filelength;
81
inputbuf = new unsigned char[inputbuf_len];
82
if (fread(inputbuf,1,mp3filelength,file) != mp3filelength)
83
cout << "Error reading mp3-file.\n" << flush;
84
// Transfer it to the mad stream-buffer:
85
mad_stream_init(&Stream);
86
mad_stream_buffer(&Stream, inputbuf, mp3filelength);
88
Read and decode the header:
91
mad_header_init(&Header);
92
// Make a table of the frames:
94
while (mad_header_decode(&Header, &Stream) == 0) {
95
ftable.push_back((long)(Stream.this_frame - Stream.buffer));
96
sampletable.push_back(total_bytes/2);
97
bitrate = Header.bitrate/1000;
99
(Stream.next_frame-Stream.this_frame)*SRATE*8*4/(bitrate*1000);
101
ftable[ftable.size()-1]<<":"<<sampletable[ftable.size()-1]<<":"<<bitrate << "..
106
(Stream.this_frame-Stream.buffer))*SRATE*8*4/(bitrate*1000);
107
// Calc the length of the file:
108
filelength = total_bytes/2; // filelength is measured in samples.
109
mad_header_finish(&Header);
111
mad_stream_finish(&Stream);
112
mad_stream_init(&Stream);
113
mad_stream_buffer(&Stream, inputbuf, mp3filelength);
114
cout << filelength << ":" << bitrate <<"\n";
117
mp3file::~mp3file() {
120
mad_stream_finish(&Stream);
121
mad_frame_finish(&Frame);
122
mad_synth_finish(&Synth);
125
Seek towards filepos (in samples). Return the position which was actually
128
long mp3file::seek(long filepos) {
130
for (i=0; (i<ftable.size()) && (sampletable[i]<filepos); i++);
132
mad_stream_finish(&Stream);
133
mad_stream_init(&Stream);
134
mad_stream_buffer(&Stream, inputbuf+ftable[i], mp3filelength-ftable[i]);
135
cout << ftable[i] << "\n";
136
return sampletable[i];
140
Read <samples_wanted> samples into the buffer <destination>.
142
unsigned mp3file::read(unsigned long samples_wanted, const SAMPLE* _destination)
144
SAMPLE *destination = (SAMPLE*)_destination;
145
unsigned Total_samples_decoded = 0;
147
while (Total_samples_decoded < samples_wanted) {
148
cout << Total_samples_decoded << ",";
149
if(mad_frame_decode(&Frame,&Stream))
150
if(MAD_RECOVERABLE(Stream.error))
152
fprintf(stderr,"Recoverable frame level error (%s)\n",
153
mad_stream_errorstr(&Stream));
158
if(Stream.error==MAD_ERROR_BUFLEN)
162
fprintf(stderr,"Unrecoverable frame level error (%s).\n",
163
mad_stream_errorstr(&Stream));
166
/* Once decoded the frame is synthesized to PCM samples. No errors
167
* are reported by mad_synth_frame();
169
mad_synth_frame(&Synth,&Frame);
170
/* Synthesized samples must be converted from mad's fixed
171
* point number to the consumer format. Here we use unsigned
172
* 16 bit big endian integers on two channels. Integer samples
173
* are temporarily stored in a buffer that is flushed when
176
for(int i=0;i<Synth.pcm.length;i++)
178
unsigned short Sample;
180
Sample=(SAMPLE)(Synth.pcm.samples[0][i]>>(MAD_F_FRACBITS-15));
181
*(destination++) = Sample;
182
/* Right channel. If the decoded stream is monophonic then
183
* the right output channel is the same as the left one.
185
if(MAD_NCHANNELS(&Frame.header)==2)
186
Sample=(SAMPLE)(Synth.pcm.samples[0][i]>>(MAD_F_FRACBITS-15));
187
*(destination++) = Sample;
189
Total_samples_decoded += 2*Synth.pcm.length;
192
cout << "decoded " << Total_samples_decoded << "\n" << flush;
194
return Total_samples_decoded;
197
long unsigned mp3file::length() {