Jack2 1.9.10

JackLibSampleRateResampler.cpp

00001 /*
00002 Copyright (C) 2008 Grame
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #include "JackLibSampleRateResampler.h"
00021 #include "JackError.h"
00022 
00023 namespace Jack
00024 {
00025 
00026 JackLibSampleRateResampler::JackLibSampleRateResampler()
00027     :JackResampler()
00028 {
00029     int error;
00030     fResampler = src_new(SRC_LINEAR, 1, &error);
00031     if (error != 0) {
00032         jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error));
00033     }
00034 }
00035 
00036 JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality)
00037     :JackResampler()
00038 {
00039      switch (quality) {
00040        case 0:
00041             quality = SRC_LINEAR;
00042             break;
00043         case 1:
00044             quality = SRC_ZERO_ORDER_HOLD;
00045             break;
00046         case 2:
00047             quality = SRC_SINC_FASTEST;
00048             break;
00049         case 3:
00050             quality = SRC_SINC_MEDIUM_QUALITY;
00051             break;
00052         case 4:
00053             quality = SRC_SINC_BEST_QUALITY;
00054             break;
00055         default:
00056             quality = SRC_LINEAR;
00057             jack_error("Out of range resample quality");
00058             break;
00059     }
00060 
00061     int error;
00062     fResampler = src_new(quality, 1, &error);
00063     if (error != 0) {
00064         jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error));
00065     }
00066 }
00067 
00068 JackLibSampleRateResampler::~JackLibSampleRateResampler()
00069 {
00070     src_delete(fResampler);
00071 }
00072 
00073 void JackLibSampleRateResampler::Reset(unsigned int new_size)
00074 {
00075     JackResampler::Reset(new_size);
00076     src_reset(fResampler);
00077 }
00078 
00079 unsigned int JackLibSampleRateResampler::ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames)
00080 {
00081     jack_ringbuffer_data_t ring_buffer_data[2];
00082     SRC_DATA src_data;
00083     unsigned int frames_to_write = frames;
00084     unsigned int written_frames = 0;
00085     int res;
00086 
00087     jack_ringbuffer_get_read_vector(fRingBuffer, ring_buffer_data);
00088     unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(jack_default_audio_sample_t);
00089     jack_log("Output available = %ld", available_frames);
00090 
00091     for (int j = 0; j < 2; j++) {
00092 
00093         if (ring_buffer_data[j].len > 0) {
00094 
00095             src_data.data_in = (jack_default_audio_sample_t*)ring_buffer_data[j].buf;
00096             src_data.data_out = &buffer[written_frames];
00097             src_data.input_frames = ring_buffer_data[j].len / sizeof(jack_default_audio_sample_t);
00098             src_data.output_frames = frames_to_write;
00099             src_data.end_of_input = 0;
00100             src_data.src_ratio = fRatio;
00101 
00102             res = src_process(fResampler, &src_data);
00103             if (res != 0) {
00104                 jack_error("JackLibSampleRateResampler::ReadResample ratio = %f err = %s", fRatio, src_strerror(res));
00105                 return 0;
00106             }
00107 
00108             frames_to_write -= src_data.output_frames_gen;
00109             written_frames += src_data.output_frames_gen;
00110 
00111             if ((src_data.input_frames_used == 0 || src_data.output_frames_gen == 0) && j == 0) {
00112                 jack_log("Output : j = %d input_frames_used = %ld output_frames_gen = %ld frames1 = %lu frames2 = %lu"
00113                     , j, src_data.input_frames_used, src_data.output_frames_gen, ring_buffer_data[0].len, ring_buffer_data[1].len);
00114             }
00115 
00116             jack_log("Output : j = %d input_frames_used = %ld output_frames_gen = %ld", j, src_data.input_frames_used, src_data.output_frames_gen);
00117             jack_ringbuffer_read_advance(fRingBuffer, src_data.input_frames_used * sizeof(jack_default_audio_sample_t));
00118         }
00119     }
00120 
00121     if (written_frames < frames) {
00122         jack_error("Output available = %ld", available_frames);
00123         jack_error("JackLibSampleRateResampler::ReadResample error written_frames = %ld", written_frames);
00124     }
00125 
00126     return written_frames;
00127 }
00128 
00129 unsigned int JackLibSampleRateResampler::WriteResample(jack_default_audio_sample_t* buffer, unsigned int frames)
00130 {
00131     jack_ringbuffer_data_t ring_buffer_data[2];
00132     SRC_DATA src_data;
00133     unsigned int frames_to_read = frames;
00134     unsigned int read_frames = 0;
00135     int res;
00136 
00137     jack_ringbuffer_get_write_vector(fRingBuffer, ring_buffer_data);
00138     unsigned int available_frames = (ring_buffer_data[0].len + ring_buffer_data[1].len) / sizeof(jack_default_audio_sample_t);
00139     jack_log("Input available = %ld", available_frames);
00140 
00141     for (int j = 0; j < 2; j++) {
00142 
00143         if (ring_buffer_data[j].len > 0) {
00144 
00145             src_data.data_in = &buffer[read_frames];
00146             src_data.data_out = (jack_default_audio_sample_t*)ring_buffer_data[j].buf;
00147             src_data.input_frames = frames_to_read;
00148             src_data.output_frames = (ring_buffer_data[j].len / sizeof(jack_default_audio_sample_t));
00149             src_data.end_of_input = 0;
00150             src_data.src_ratio = fRatio;
00151 
00152             res = src_process(fResampler, &src_data);
00153             if (res != 0) {
00154                 jack_error("JackLibSampleRateResampler::WriteResample ratio = %f err = %s", fRatio, src_strerror(res));
00155                 return 0;
00156             }
00157 
00158             frames_to_read -= src_data.input_frames_used;
00159             read_frames += src_data.input_frames_used;
00160 
00161             if ((src_data.input_frames_used == 0 || src_data.output_frames_gen == 0) && j == 0) {
00162                 jack_log("Input : j = %d input_frames_used = %ld output_frames_gen = %ld frames1 = %lu frames2 = %lu"
00163                     , j, src_data.input_frames_used, src_data.output_frames_gen, ring_buffer_data[0].len, ring_buffer_data[1].len);
00164             }
00165 
00166             jack_log("Input : j = %d input_frames_used = %ld output_frames_gen = %ld", j, src_data.input_frames_used, src_data.output_frames_gen);
00167             jack_ringbuffer_write_advance(fRingBuffer, src_data.output_frames_gen * sizeof(jack_default_audio_sample_t));
00168         }
00169     }
00170 
00171     if (read_frames < frames) {
00172         jack_error("Input available = %ld", available_frames);
00173         jack_error("JackLibSampleRateResampler::WriteResample error read_frames = %ld", read_frames);
00174     }
00175 
00176     return read_frames;
00177 }
00178 
00179 }