Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

resampler.cpp

Go to the documentation of this file.
00001 #include "resampler.h"
00002 
00003 
00004 namespace audiere {
00005 
00006   Resampler::Resampler(SampleSource* source, int rate) {
00007     m_source = source;
00008     m_rate = rate;
00009     m_source->getFormat(
00010       m_native_channel_count,
00011       m_native_sample_rate,
00012       m_native_sample_format);
00013 
00014     m_shift = 1;
00015 
00016     fillBuffer();
00017     resetState();
00018   }
00019 
00020   void
00021   Resampler::getFormat(
00022     int& channel_count,
00023     int& sample_rate,
00024     SampleFormat& sample_format)
00025   {
00026     channel_count = 2;
00027     sample_rate = m_rate;
00028     sample_format = SF_S16;
00029   }
00030 
00031   int
00032   Resampler::read(const int frame_count, void* buffer) {
00033     u16* out = (u16*)buffer;
00034 
00035     int left = frame_count;
00036 
00037     // if we didn't finish resampling last time...
00038     while (m_time > m_native_sample_rate && left > 0) {
00039       m_time -= m_native_sample_rate;
00040       *out++ = m_sl;
00041       *out++ = m_sr;
00042       --left;
00043     }
00044 
00045     while (left > 0) {
00046 
00047       if (m_samples_left == 0) {
00048         // try to fill the native buffer
00049         fillBuffer();
00050 
00051         // could we read any more?
00052         if (m_samples_left == 0) {
00053           return frame_count - left;
00054         }
00055       }
00056 
00057       m_sl = *m_position++;
00058       m_sr = *m_position++;
00059       --m_samples_left;
00060 
00061       m_time += m_rate / m_shift;
00062       while (m_time > m_native_sample_rate && left > 0) {
00063         m_time -= m_native_sample_rate;
00064         *out++ = m_sl;
00065         *out++ = m_sr;
00066         --left;
00067       }
00068 
00069     }
00070     return frame_count;
00071   }
00072 
00073   void
00074   Resampler::reset() {
00075     m_source->reset();
00076     fillBuffer();
00077     resetState();
00078   }
00079 
00080 
00081   inline s16 u8tos16(u8 u) {
00082     return (s16(u) - 128) * 256;
00083   }
00084 
00085   void
00086   Resampler::fillBuffer() {
00087     // we only support channels in [1, 2] and bits in [8, 16] now
00088     u8 initial_buffer[NATIVE_BUFFER_SIZE * 4];
00089     unsigned read = m_source->read(NATIVE_BUFFER_SIZE, initial_buffer);
00090 
00091     s16* out = m_native_buffer;
00092 
00093     if (m_native_channel_count == 1) {
00094       if (m_native_sample_format == SF_U8) {
00095 
00096         // channels = 1, bits = 8
00097         u8* in = initial_buffer;
00098         for (unsigned i = 0; i < read; ++i) {
00099           s16 sample = u8tos16(*in++);
00100           *out++ = sample;
00101           *out++ = sample;
00102         }
00103 
00104       } else {
00105 
00106         // channels = 1, bits = 16
00107         s16* in = (s16*)initial_buffer;
00108         for (unsigned i = 0; i < read; ++i) {
00109           s16 sample = *in++;
00110           *out++ = sample;
00111           *out++ = sample;
00112         }
00113 
00114       }
00115     } else {
00116       if (m_native_sample_format == SF_U8) {
00117 
00118         // channels = 2, bits = 8
00119         u8* in = initial_buffer;
00120         for (unsigned i = 0; i < read; ++i) {
00121           *out++ = u8tos16(*in++);
00122           *out++ = u8tos16(*in++);
00123         }
00124 
00125       } else {
00126 
00127         // channels = 2, bits = 16
00128         s16* in = (s16*)initial_buffer;
00129         for (unsigned i = 0; i < read; ++i) {
00130           *out++ = *in++;
00131           *out++ = *in++;
00132         }
00133       
00134       }
00135     }
00136 
00137     m_position = m_native_buffer;
00138     m_samples_left = read;
00139   }
00140 
00141   void
00142   Resampler::resetState() {
00143     m_time = 0;
00144     m_sl = 0;
00145     m_sr = 0;
00146   }
00147 
00148   bool
00149   Resampler::isSeekable() {
00150     return m_source->isSeekable();
00151   }
00152 
00153   int
00154   Resampler::getLength() {
00155     return m_source->getLength();
00156   }
00157 
00158   void
00159   Resampler::setPosition(int position) {
00160     m_source->setPosition(position);
00161     fillBuffer();
00162     resetState();
00163   }
00164 
00165   int
00166   Resampler::getPosition() {
00167     return m_source->getPosition() - m_samples_left;
00168   }
00169 
00170   void
00171   Resampler::setPitchShift(float shift) {
00172     m_shift = shift;
00173   }
00174 
00175   float
00176   Resampler::getPitchShift() {
00177     return m_shift;
00178   }
00179 
00180 }

Generated on Sat Oct 12 01:43:04 2002 for audiere by doxygen1.2.17