the most basic, generally not-correct linear interpolating resampling filter

pull/18/head
Dimitri Diakopoulos 10 years ago
parent 892c798f9f
commit ce56c943b9

@ -40,8 +40,8 @@ int main(int argc, const char **argv) try
// 1-channel wave // 1-channel wave
//loader.Load(fileData.get(), "test_data/1ch/44100/8/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/8/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/16/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/16/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav"); loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav");
loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/64/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/64/test.wav");
// 2-channel wave // 2-channel wave
@ -104,6 +104,13 @@ int main(int argc, const char **argv) try
std::cout << "[Warning - Sample Rate Mismatch] - file is sampled at " << fileData->sampleRate << " and output is " << desiredSampleRate << std::endl; std::cout << "[Warning - Sample Rate Mismatch] - file is sampled at " << fileData->sampleRate << " and output is " << desiredSampleRate << std::endl;
} }
std::vector<float> outputBuffer;
outputBuffer.reserve(fileData->samples.size());
linear_resample(44100.0 / 48000.0, fileData->samples, outputBuffer, fileData->samples.size());
std::cout << "Input Samples: " << fileData->samples.size() << std::endl;
std::cout << "Output Samples: " << outputBuffer.size() << std::endl;
// Convert mono to stereo for testing playback // Convert mono to stereo for testing playback
if (fileData->channelCount == 1) if (fileData->channelCount == 1)
{ {
@ -118,6 +125,7 @@ int main(int argc, const char **argv) try
myDevice.Play(fileData->samples); myDevice.Play(fileData->samples);
} }
fileData->samples = outputBuffer;
int encoderStatus = OggOpusEncoder::WriteFile({1, PCM_FLT, DITHER_NONE}, fileData.get(), "encoded.opus"); int encoderStatus = OggOpusEncoder::WriteFile({1, PCM_FLT, DITHER_NONE}, fileData.get(), "encoded.opus");
std::cout << "Encoder Status: " << encoderStatus << std::endl; std::cout << "Encoder Status: " << encoderStatus << std::endl;

@ -33,32 +33,55 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace nqr namespace nqr
{ {
enum EncoderError static inline void linear_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, size_t samplesToProcess)
{ {
NoError, float * source = const_cast<float *>(input.data());
InsufficientSampleData,
FileIOError, double virtualReadIndex = 0;
UnsupportedSamplerate,
UnsupportedChannelConfiguration, // Linear Interpolate
UnsupportedBitdepth, int n = samplesToProcess - 1;
UnsupportedChannelMix, while (n--)
BufferTooBig, {
}; unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
double interpolationFactor = virtualReadIndex - readIndex;
double sample1 = source[readIndex];
double sample2 = source[readIndex + 1];
double sample = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2;
output.push_back(sample);
virtualReadIndex += rate;
}
}
enum EncoderError
{
NoError,
InsufficientSampleData,
FileIOError,
UnsupportedSamplerate,
UnsupportedChannelConfiguration,
UnsupportedBitdepth,
UnsupportedChannelMix,
BufferTooBig,
};
// A simplistic encoder that takes a blob of data, conforms it to the user's
// EncoderParams preference, and writes to disk. Be warned, does not support resampling!
// @todo support dithering, samplerate conversion, etc.
struct WavEncoder
{
// Assume data adheres to EncoderParams, except for bit depth and fmt
static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path);
};
// A simplistic encoder that takes a blob of data, conforms it to the user's struct OggOpusEncoder
// EncoderParams preference, and writes to disk. Be warned, does not support resampling! {
// @todo support dithering, samplerate conversion, etc. static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path);
struct WavEncoder };
{
// Assume data adheres to EncoderParams, except for bit depth and fmt
static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path);
};
struct OggOpusEncoder
{
static int WriteFile(const EncoderParams p, const AudioData * d, const std::string & path);
};
} // end namespace nqr } // end namespace nqr

@ -450,4 +450,4 @@ int OggOpusEncoder::WriteFile(const EncoderParams p, const AudioData * d, const
return EncoderError::NoError; return EncoderError::NoError;
} }
#undef OPUS_MAX_PACKET_SIZE #undef OPUS_MAX_PACKET_SIZE
Loading…
Cancel
Save