input_speex.cpp

Go to the documentation of this file.
00001 #include "debug.h"
00002 #include "input_speex.h"
00003 
00004 
00005 namespace audiere {
00006 
00007   class FileReader : public speexfile::Reader {
00008   private:
00009     FilePtr m_file;
00010     bool m_seekable;
00011 
00012   public:
00013     FileReader(FilePtr file) {
00014       m_file = file;
00015 
00016       // Hacky test to see whether we can seek in the file.
00017       m_seekable = m_file->seek(0, File::BEGIN);
00018     }
00019 
00020     int read(void* ptr, int size) {
00021       return m_file->read(ptr, size);
00022     }
00023 
00024     speexfile::offset_t seek(speexfile::offset_t offset) {
00025       m_file->seek(static_cast<int>(offset), File::BEGIN);
00026       return get_position();
00027     }
00028 
00029     speexfile::offset_t get_position() {
00030       return m_file->tell();
00031     }
00032 
00033     speexfile::offset_t get_length() {
00034       speexfile::offset_t c = get_position();
00035       m_file->seek(0, File::END);
00036       speexfile::offset_t l = get_position();
00037       m_file->seek(static_cast<int>(c), File::BEGIN);
00038       return l;
00039     }
00040 
00041     bool can_seek() {
00042       return m_seekable;
00043     }
00044   };
00045 
00046 
00047   SpeexInputStream::SpeexInputStream() {
00048     m_speexfile = 0;
00049     m_position = 0;
00050   }
00051 
00052 
00053   SpeexInputStream::~SpeexInputStream() {
00054     delete m_speexfile;
00055   }
00056 
00057 
00059   bool
00060   SpeexInputStream::initialize(FilePtr file) {
00061 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00062     m_reader = std::auto_ptr<speexfile::Reader>(new FileReader(file));
00063 #else
00064     m_reader.reset(new FileReader(file));
00065 #endif
00066     m_speexfile = new speexfile::speexfile(m_reader.get());
00067 
00068     // @todo How should we handle files with multiple streams?
00069     if (m_speexfile->get_streams() != 1) {
00070       delete m_speexfile;
00071       m_speexfile = 0;
00072       return false;
00073     }
00074 
00075     speexfile::int32_t rate     = m_speexfile->stream_get_samplerate();
00076     speexfile::int32_t channels = m_speexfile->stream_get_channels();
00077     if (rate == 0 || channels == 0) {
00078       delete m_speexfile;
00079       m_speexfile = 0;
00080       return false;
00081     }
00082 
00083     for (int i = 0; i < m_speexfile->stream_get_tagcount(); ++i) {
00084       const speexfile::speextags* tag = m_speexfile->stream_get_tags()[i];
00085       addTag(
00086         tag->item ? tag->item : "",
00087         tag->value ? tag->value : "",
00088         "Speex");
00089     }
00090 
00091     return true;
00092   }
00093 
00094 
00095   void
00096   SpeexInputStream::getFormat(
00097     int& channel_count,
00098     int& sample_rate,
00099     SampleFormat& sample_format)
00100   {
00101     channel_count = m_speexfile->stream_get_channels();
00102     sample_rate   = m_speexfile->stream_get_samplerate();
00103     sample_format = SF_S16;
00104   }
00105 
00106 
00107   int
00108   SpeexInputStream::doRead(int frame_count, void* buffer) {
00109     s16* out = (s16*)buffer;
00110 
00111     int total_read = 0;
00112     while (frame_count > 0) {
00113       // If the buffer is empty, decode a little from the speex file.
00114       if (m_read_buffer.getSize() == 0) {
00115         float decode_buffer[2000];  // Size defined by speexfile API.
00116         int speex_read = m_speexfile->decode(decode_buffer);
00117         if (speex_read == 0) {
00118           break;
00119         }
00120 
00121         m_read_buffer.write(decode_buffer, speex_read * sizeof(float));
00122       }
00123 
00124       const int BUFFER_SIZE = 1024;
00125       float read_buffer[BUFFER_SIZE];
00126 
00127       int should_read = std::min(frame_count, BUFFER_SIZE);
00128       int actual_read = m_read_buffer.read(read_buffer, should_read * sizeof(float)) / sizeof(float);
00129       ADR_ASSERT(actual_read != 0, "Read queue should have data");
00130 
00131       for (int i = 0; i < actual_read; ++i) {
00132         out[i] = s16(read_buffer[i] * 32767);
00133       }
00134 
00135       frame_count -= actual_read;
00136       total_read += actual_read;
00137       out += actual_read;
00138     }
00139     m_position += total_read;
00140     return total_read;
00141   }
00142 
00143 
00144   void
00145   SpeexInputStream::reset() {
00146     setPosition(0);  // need to update m_position
00147   }
00148 
00149 
00150   bool
00151   SpeexInputStream::isSeekable() {
00152     return true;
00153   }
00154 
00155 
00156   int
00157   SpeexInputStream::getLength() {
00158     return static_cast<int>(m_speexfile->get_samples());
00159   }
00160 
00161 
00162   void
00163   SpeexInputStream::setPosition(int position) {
00164     m_speexfile->seek_sample(position);
00165     m_position = position;
00166   }
00167 
00168 
00169   int
00170   SpeexInputStream::getPosition() {
00171     return m_position;
00172   }
00173 
00174 }

Generated on Mon Feb 13 23:07:47 2006 for audiere by  doxygen 1.4.6