1 /**
2 * @file
3 * @brief Source file for AudioResampler class
4 * @author Jonathan Thomas <jonathan@openshot.org>
5 *
6 * @ref License
7 */
8
9 /* LICENSE
10 *
11 * Copyright (c) 2008-2019 OpenShot Studios, LLC
12 * <http://www.openshotstudios.com/>. This file is part of
13 * OpenShot Library (libopenshot), an open-source project dedicated to
14 * delivering high quality video editing and animation solutions to the
15 * world. For more information visit <http://www.openshot.org/>.
16 *
17 * OpenShot Library (libopenshot) is free software: you can redistribute it
18 * and/or modify it under the terms of the GNU Lesser General Public License
19 * as published by the Free Software Foundation, either version 3 of the
20 * License, or (at your option) any later version.
21 *
22 * OpenShot Library (libopenshot) is distributed in the hope that it will be
23 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public License
28 * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include "AudioResampler.h"
32
33 using namespace std;
34 using namespace openshot;
35
36 // Default constructor, max frames to cache is 20 // resample_source(NULL), buffer_source(NULL), num_of_samples(0), new_num_of_samples(0), dest_ratio(0), source_ratio(0), resampled_buffer(NULL), isPrepared(false)
AudioResampler()37 AudioResampler::AudioResampler()
38 {
39 resample_source = NULL;
40 buffer_source = NULL;
41 num_of_samples = 0;
42 new_num_of_samples = 0;
43 dest_ratio = 0;
44 source_ratio = 0;
45 resampled_buffer = NULL;
46 isPrepared = false;
47
48 // Init buffer source
49 buffer_source = new AudioBufferSource(buffer);
50
51 // Init resampling source
52 resample_source = new juce::ResamplingAudioSource(buffer_source, false, 2);
53
54 // Init resampled buffer
55 resampled_buffer = new juce::AudioSampleBuffer(2, 1);
56 resampled_buffer->clear();
57
58 // Init callback buffer
59 resample_callback_buffer.buffer = resampled_buffer;
60 resample_callback_buffer.numSamples = 1;
61 resample_callback_buffer.startSample = 0;
62 }
63
64 // Descructor
~AudioResampler()65 AudioResampler::~AudioResampler()
66 {
67 // Clean up
68 if (buffer_source)
69 delete buffer_source;
70 if (resample_source)
71 delete resample_source;
72 if (resampled_buffer)
73 delete resampled_buffer;
74 }
75
76 // Sets the audio buffer and updates the key settings
SetBuffer(juce::AudioSampleBuffer * new_buffer,double sample_rate,double new_sample_rate)77 void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate)
78 {
79 if (sample_rate <= 0)
80 sample_rate = 44100;
81 if (new_sample_rate <= 0)
82 new_sample_rate = 44100;
83
84 // Set the sample ratio (the ratio of sample rate change)
85 source_ratio = sample_rate / new_sample_rate;
86
87 // Call SetBuffer with ratio
88 SetBuffer(new_buffer, source_ratio);
89 }
90
91 // Sets the audio buffer and key settings
SetBuffer(juce::AudioSampleBuffer * new_buffer,double ratio)92 void AudioResampler::SetBuffer(juce::AudioSampleBuffer *new_buffer, double ratio)
93 {
94 // Update buffer & buffer source
95 buffer = new_buffer;
96 buffer_source->setBuffer(buffer);
97
98 // Set the sample ratio (the ratio of sample rate change)
99 source_ratio = ratio;
100 dest_ratio = 1.0 / ratio;
101 num_of_samples = buffer->getNumSamples();
102 new_num_of_samples = round(num_of_samples * dest_ratio) - 1;
103
104 // Set resample ratio
105 resample_source->setResamplingRatio(source_ratio);
106
107 // Prepare to play resample source
108 if (!isPrepared)
109 {
110 // Prepare to play the audio sources (and set the # of samples per chunk to a little more than expected)
111 resample_source->prepareToPlay(num_of_samples + 10, 0);
112 isPrepared = true;
113 }
114
115 // Resize buffer for the newly resampled data
116 resampled_buffer->setSize(buffer->getNumChannels(), new_num_of_samples, true, true, true);
117 resample_callback_buffer.numSamples = new_num_of_samples;
118 resample_callback_buffer.startSample = 0;
119 resample_callback_buffer.clearActiveBufferRegion();
120 }
121
122 // Get the resampled audio buffer
GetResampledBuffer()123 juce::AudioSampleBuffer* AudioResampler::GetResampledBuffer()
124 {
125 // Resample the current frame's audio buffer (into the temp callback buffer)
126 resample_source->getNextAudioBlock(resample_callback_buffer);
127
128 // Return buffer pointer to this newly resampled buffer
129 return resampled_buffer;
130 }
131