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     fillBuffers();
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     s16* out = (s16*)buffer;
00034     int left = frame_count;
00035     sample_t tmp_l[BUFFER_SIZE];
00036     sample_t tmp_r[BUFFER_SIZE];
00037     float delta = m_shift * m_native_sample_rate / m_rate;
00038     if (m_shift == 0) {  // If shift is zero, which shouldn't be the case, use a shift of 1.
00039       delta = float(m_native_sample_rate / m_rate);
00040     }
00041     while (left > 0) {
00042       int transfer = std::min(left, int(BUFFER_SIZE));
00043       memset(tmp_l, 0, transfer * sizeof(sample_t));
00044       int rv = dumb_resample(&m_resampler_l, tmp_l, transfer, 1.0, delta);
00045       if (rv == 0) {
00046         fillBuffers();
00047         if (m_buffer_length == 0) {
00048           return frame_count - left;
00049         } else {
00050           m_resampler_l.pos = m_resampler_l.subpos = m_resampler_l.start = 0;
00051           m_resampler_l.end = m_buffer_length;
00052           m_resampler_l.dir = 1;
00053           m_resampler_r.pos = m_resampler_r.subpos = m_resampler_r.start = 0;
00054           m_resampler_r.end = m_buffer_length;
00055           m_resampler_r.dir = 1;
00056           continue;
00057         }
00058       }
00059       if (m_native_channel_count == 2) {
00060         memset(tmp_r, 0, transfer * sizeof(sample_t));
00061         int rv2 = dumb_resample(&m_resampler_r, tmp_r, transfer, 1.0,
00062                                 delta);
00063         ADR_ASSERT(rv == rv2, "resamplers returned different sample counts");
00064         for (int i = 0; i < rv; i++) {
00065           *out++ = clamp(-32768, tmp_l[i], 32767);
00066           *out++ = clamp(-32768, tmp_r[i], 32767);
00067         }
00068       } else {
00069         for (int i = 0; i < rv; i++) {
00070           s16 sample = clamp(-32768, tmp_l[i], 32767);
00071           *out++ = sample;
00072           *out++ = sample;
00073         }
00074       }
00075       left -= rv;
00076     }
00077     return frame_count;
00078   }
00079 
00080   void
00081   Resampler::reset() {
00082     m_source->reset();
00083     fillBuffers();
00084     resetState();
00085   }
00086 
00087 
00088   inline s16 u8tos16(u8 u) {
00089     return (s16(u) - 128) * 256;
00090   }
00091 
00092   void
00093   Resampler::fillBuffers() {
00094     // we only support channels in [1, 2] and bits in [8, 16] now
00095     u8 initial_buffer[BUFFER_SIZE * 4];
00096     unsigned read = m_source->read(BUFFER_SIZE, initial_buffer);
00097 
00098     sample_t* out_l = m_native_buffer_l;
00099     sample_t* out_r = m_native_buffer_r;
00100 
00101     if (m_native_channel_count == 1) {
00102       if (m_native_sample_format == SF_U8) {
00103 
00104         // channels = 1, bits = 8
00105         u8* in = initial_buffer;
00106         for (unsigned i = 0; i < read; ++i) {
00107           s16 sample = u8tos16(*in++);
00108           *out_l++ = sample;
00109         }
00110 
00111       } else {
00112 
00113         // channels = 1, bits = 16
00114         s16* in = (s16*)initial_buffer;
00115         for (unsigned i = 0; i < read; ++i) {
00116           s16 sample = *in++;
00117           *out_l++ = sample;
00118         }
00119 
00120       }
00121     } else {
00122       if (m_native_sample_format == SF_U8) {
00123 
00124         // channels = 2, bits = 8
00125         u8* in = initial_buffer;
00126         for (unsigned i = 0; i < read; ++i) {
00127           *out_l++ = u8tos16(*in++);
00128           *out_r++ = u8tos16(*in++);
00129         }
00130 
00131       } else {
00132 
00133         // channels = 2, bits = 16
00134         s16* in = (s16*)initial_buffer;
00135         for (unsigned i = 0; i < read; ++i) {
00136           *out_l++ = *in++;
00137           *out_r++ = *in++;
00138         }
00139       
00140       }
00141     }
00142 
00143     m_buffer_length = read;
00144   }
00145 
00146   void
00147   Resampler::resetState() {
00148     dumb_reset_resampler(&m_resampler_l, m_native_buffer_l, 0, 0,
00149                          m_buffer_length);
00150     if (m_native_channel_count == 2) {
00151       dumb_reset_resampler(&m_resampler_r, m_native_buffer_r, 0, 0,
00152                            m_buffer_length);
00153     }
00154   }
00155 
00156   bool
00157   Resampler::isSeekable() {
00158     return m_source->isSeekable();
00159   }
00160 
00161   int
00162   Resampler::getLength() {
00163     return m_source->getLength();
00164   }
00165 
00166   void
00167   Resampler::setPosition(int position) {
00168     m_source->setPosition(position);
00169     fillBuffers();
00170     resetState();
00171   }
00172 
00173   int
00174   Resampler::getPosition() {
00175     int position = m_source->getPosition() - m_buffer_length +
00176                    m_resampler_l.pos;
00177     while (position < 0) {
00178       position += m_source->getLength();
00179     }
00180     return position;
00181   }
00182 
00183   bool
00184   Resampler::getRepeat() {
00185     return m_source->getRepeat();
00186   }
00187 
00188   void
00189   Resampler::setRepeat(bool repeat) {
00191     m_source->setRepeat(repeat);
00192   }
00193 
00194   int Resampler::getTagCount()              { return m_source->getTagCount();  }
00195   const char* Resampler::getTagKey(int i)   { return m_source->getTagKey(i);   }
00196   const char* Resampler::getTagValue(int i) { return m_source->getTagValue(i); }
00197   const char* Resampler::getTagType(int i)  { return m_source->getTagType(i);  }
00198 
00199   void
00200   Resampler::setPitchShift(float shift) {
00201     m_shift = shift;
00202   }
00203 
00204   float
00205   Resampler::getPitchShift() {
00206     return m_shift;
00207   }
00208 
00209 }

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