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

resampler.cpp

Go to the documentation of this file.
00001 #include "resampler.hpp"
00002 
00003 
00005 
00006 Resampler::Resampler(ISampleSource* source)
00007 {
00008   m_source = source;
00009   m_source->GetFormat(
00010     m_native_channel_count,
00011     m_native_sample_rate,
00012     m_native_bits_per_sample);
00013 
00014   FillBuffer();
00015   ResetState();
00016 }
00017 
00019 
00020 Resampler::~Resampler()
00021 {
00022 }
00023 
00025 
00026 void
00027 Resampler::GetFormat(int& channel_count, int& sample_rate, int& bits_per_sample)
00028 {
00029   channel_count = 2;
00030   sample_rate = 44100;
00031   bits_per_sample = 16;
00032 }
00033 
00035 
00036 int
00037 Resampler::Read(const int sample_count, void* samples)
00038 {
00039   adr_u16* out = (adr_u16*)samples;
00040 
00041   int left = sample_count;
00042 
00043   // if we didn't finish resampling last time...
00044   while (m_time > m_native_sample_rate && left > 0) {
00045     m_time -= m_native_sample_rate;
00046     *out++ = m_sl;
00047     *out++ = m_sr;
00048     --left;
00049   }
00050 
00051   while (left > 0) {
00052 
00053     if (m_samples_left == 0) {
00054       // try to fill the native buffer
00055       FillBuffer();
00056 
00057       // could we read any more?
00058       if (m_samples_left == 0) {
00059         return sample_count - left;
00060       }
00061     }
00062 
00063     m_sl = *m_position++;
00064     m_sr = *m_position++;
00065     --m_samples_left;
00066 
00067     m_time += 44100;
00068     while (m_time > m_native_sample_rate && left > 0) {
00069       m_time -= m_native_sample_rate;
00070       *out++ = m_sl;
00071       *out++ = m_sr;
00072       --left;
00073     }
00074 
00075   }
00076   return sample_count;
00077 }
00078 
00080 
00081 bool
00082 Resampler::Reset()
00083 {
00084   if (m_source->Reset()) {
00085     FillBuffer();
00086     ResetState();
00087     return true;
00088   } else {
00089     return false;
00090   }
00091 }
00092 
00094 
00095 inline adr_s16 u8tos16(adr_u8 u) {
00096   return (adr_s16(u) - 127) * (1 << 8);
00097 }
00098 
00099 void
00100 Resampler::FillBuffer()
00101 {
00102   // we only support channels in [1, 2] and bits in [8, 16] now
00103   adr_u8 initial_buffer[NATIVE_BUFFER_SIZE * 4];
00104   unsigned read = m_source->Read(NATIVE_BUFFER_SIZE, initial_buffer);
00105 
00106   adr_s16* out = m_native_buffer;
00107 
00108   if (m_native_channel_count == 1) {
00109     if (m_native_bits_per_sample == 8) {
00110 
00111       // channels = 1, bits = 8
00112       adr_u8* in = initial_buffer;
00113       for (unsigned i = 0; i < read; ++i) {
00114         adr_s16 sample = u8tos16(*in++);
00115         *out++ = sample;
00116         *out++ = sample;
00117       }
00118 
00119     } else {
00120 
00121       // channels = 1, bits = 16
00122       adr_s16* in = (adr_s16*)initial_buffer;
00123       for (unsigned i = 0; i < read; ++i) {
00124         adr_s16 sample = *in++;
00125         *out++ = sample;
00126         *out++ = sample;
00127       }
00128 
00129     }
00130   } else {
00131     if (m_native_bits_per_sample == 8) {
00132 
00133       // channels = 2, bits = 8
00134       adr_u8* in = initial_buffer;
00135       for (unsigned i = 0; i < read; ++i) {
00136         *out++ = u8tos16(*in++);
00137         *out++ = u8tos16(*in++);
00138       }
00139 
00140     } else {
00141 
00142       // channels = 2, bits = 16
00143       adr_s16* in = (adr_s16*)initial_buffer;
00144       for (unsigned i = 0; i < read; ++i) {
00145         *out++ = *in++;
00146         *out++ = *in++;
00147       }
00148       
00149     }
00150   }
00151 
00152   m_position = m_native_buffer;
00153   m_samples_left = read;
00154 }
00155 
00157 
00158 void
00159 Resampler::ResetState()
00160 {
00161   m_time = 0;
00162   m_sl = 0;
00163   m_sr = 0;
00164 }
00165 

Generated at Mon Jun 10 02:55:12 2002 for audiere by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001