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) {
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
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
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
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
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
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 }