@@ -182,23 +182,12 @@ bool StretchAudioSource::isPreviewingDry() const | |||||
void StretchAudioSource::getNextAudioBlock(const AudioSourceChannelInfo & bufferToFill) | void StretchAudioSource::getNextAudioBlock(const AudioSourceChannelInfo & bufferToFill) | ||||
{ | { | ||||
ScopedLock locker(m_cs); | ScopedLock locker(m_cs); | ||||
double maingain = Decibels::decibelsToGain(m_main_volume); | |||||
if (m_preview_dry == true && m_inputfile!=nullptr && m_inputfile->info.nsamples>0) | if (m_preview_dry == true && m_inputfile!=nullptr && m_inputfile->info.nsamples>0) | ||||
{ | { | ||||
m_inputfile->setXFadeLenSeconds(m_loopxfadelen); | |||||
double* rsinbuf = nullptr; | |||||
m_resampler->SetRates(m_inputfile->info.samplerate, m_outsr); | |||||
int wanted = m_resampler->ResamplePrepare(bufferToFill.numSamples, m_num_outchans, &rsinbuf); | |||||
m_inputfile->readNextBlock(m_drypreviewbuf, wanted, m_num_outchans); | |||||
for (int i = 0; i < wanted; ++i) | |||||
for (int j = 0; j < m_num_outchans; ++j) | |||||
rsinbuf[i*m_num_outchans + j] = m_drypreviewbuf.getSample(j, i); | |||||
m_resampler->ResampleOut(m_resampler_outbuf.data(), wanted, bufferToFill.numSamples, m_num_outchans); | |||||
for (int i = 0; i < m_num_outchans; ++i) | |||||
for (int j = 0; j < bufferToFill.numSamples; ++j) | |||||
bufferToFill.buffer->setSample(i, j+bufferToFill.startSample, maingain * m_resampler_outbuf[j*m_num_outchans + i]); | |||||
playDrySound(bufferToFill); | |||||
return; | return; | ||||
} | } | ||||
double maingain = Decibels::decibelsToGain(m_main_volume); | |||||
if (m_pause_state == 2) | if (m_pause_state == 2) | ||||
{ | { | ||||
bufferToFill.buffer->clear(bufferToFill.startSample,bufferToFill.numSamples); | bufferToFill.buffer->clear(bufferToFill.startSample,bufferToFill.numSamples); | ||||
@@ -474,6 +463,23 @@ void StretchAudioSource::initObjects() | |||||
int poolsize = m_stretchers[0]->get_max_bufsize(); | int poolsize = m_stretchers[0]->get_max_bufsize(); | ||||
} | } | ||||
void StretchAudioSource::playDrySound(const AudioSourceChannelInfo & bufferToFill) | |||||
{ | |||||
double maingain = Decibels::decibelsToGain(m_main_volume); | |||||
m_inputfile->setXFadeLenSeconds(m_loopxfadelen); | |||||
double* rsinbuf = nullptr; | |||||
m_resampler->SetRates(m_inputfile->info.samplerate, m_outsr); | |||||
int wanted = m_resampler->ResamplePrepare(bufferToFill.numSamples, m_num_outchans, &rsinbuf); | |||||
m_inputfile->readNextBlock(m_drypreviewbuf, wanted, m_num_outchans); | |||||
for (int i = 0; i < wanted; ++i) | |||||
for (int j = 0; j < m_num_outchans; ++j) | |||||
rsinbuf[i*m_num_outchans + j] = m_drypreviewbuf.getSample(j, i); | |||||
m_resampler->ResampleOut(m_resampler_outbuf.data(), wanted, bufferToFill.numSamples, m_num_outchans); | |||||
for (int i = 0; i < m_num_outchans; ++i) | |||||
for (int j = 0; j < bufferToFill.numSamples; ++j) | |||||
bufferToFill.buffer->setSample(i, j + bufferToFill.startSample, maingain * m_resampler_outbuf[j*m_num_outchans + i]); | |||||
} | |||||
double StretchAudioSource::getInfilePositionPercent() | double StretchAudioSource::getInfilePositionPercent() | ||||
{ | { | ||||
if (m_inputfile == nullptr || m_inputfile->info.nsamples == 0) | if (m_inputfile == nullptr || m_inputfile->info.nsamples == 0) | ||||
@@ -157,4 +157,5 @@ private: | |||||
int m_pause_fade_counter = 0; | int m_pause_fade_counter = 0; | ||||
bool m_preview_dry = false; | bool m_preview_dry = false; | ||||
AudioBuffer<float> m_drypreviewbuf; | AudioBuffer<float> m_drypreviewbuf; | ||||
void playDrySound(const AudioSourceChannelInfo & bufferToFill); | |||||
}; | }; |
@@ -500,8 +500,11 @@ void WaveformComponent::paint(Graphics & g) | |||||
m_thumbnail->drawChannels(g, { 0,m_topmargin,getWidth(),getHeight() - m_topmargin }, | m_thumbnail->drawChannels(g, { 0,m_topmargin,getWidth(),getHeight() - m_topmargin }, | ||||
thumblen*m_view_range.getStart(), thumblen*m_view_range.getEnd(), 1.0f); | thumblen*m_view_range.getStart(), thumblen*m_view_range.getEnd(), 1.0f); | ||||
} | } | ||||
if (m_is_at_selection_drag_area) | |||||
g.setColour(Colours::white.withAlpha(0.6f)); | |||||
else | |||||
g.setColour(Colours::white.withAlpha(0.5f)); | |||||
g.setColour(Colours::white.withAlpha(0.5f)); | |||||
double sel_len = m_time_sel_end - m_time_sel_start; | double sel_len = m_time_sel_end - m_time_sel_start; | ||||
//if (sel_len > 0.0 && sel_len < 1.0) | //if (sel_len > 0.0 && sel_len < 1.0) | ||||
{ | { | ||||
@@ -607,13 +610,13 @@ void WaveformComponent::mouseDrag(const MouseEvent & e) | |||||
{ | { | ||||
if (m_didseek == true) | if (m_didseek == true) | ||||
return; | return; | ||||
if (m_time_sel_drag_target == 0 && (e.mods.isAnyModifierKeyDown()==false && e.y>=50)) | |||||
if (m_time_sel_drag_target == 0 && e.y>=50) | |||||
{ | { | ||||
m_time_sel_start = m_drag_time_start; | m_time_sel_start = m_drag_time_start; | ||||
m_time_sel_end = viewXToNormalized(e.x); | m_time_sel_end = viewXToNormalized(e.x); | ||||
} | } | ||||
double curlen = m_time_sel_end - m_time_sel_start; | double curlen = m_time_sel_end - m_time_sel_start; | ||||
if (m_time_sel_drag_target == 0 && (e.mods.isShiftDown() || e.y<50)) | |||||
if (m_time_sel_drag_target == 0 && e.y<50 && m_is_at_selection_drag_area) | |||||
{ | { | ||||
double diff = m_drag_time_start - viewXToNormalized(e.x); | double diff = m_drag_time_start - viewXToNormalized(e.x); | ||||
m_time_sel_start = jlimit<double>(0.0, 1.0-curlen, m_time_sel_start - diff); | m_time_sel_start = jlimit<double>(0.0, 1.0-curlen, m_time_sel_start - diff); | ||||
@@ -661,7 +664,8 @@ void WaveformComponent::mouseMove(const MouseEvent & e) | |||||
setMouseCursor(MouseCursor::LeftRightResizeCursor); | setMouseCursor(MouseCursor::LeftRightResizeCursor); | ||||
if (m_time_sel_drag_target == 2) | if (m_time_sel_drag_target == 2) | ||||
setMouseCursor(MouseCursor::LeftRightResizeCursor); | setMouseCursor(MouseCursor::LeftRightResizeCursor); | ||||
Range<int> temp(normalizedToViewX<int>(m_time_sel_start), normalizedToViewX<int>(m_time_sel_end)); | |||||
m_is_at_selection_drag_area = temp.contains(e.x) == true && e.y < 50; | |||||
} | } | ||||
void WaveformComponent::mouseDoubleClick(const MouseEvent & e) | void WaveformComponent::mouseDoubleClick(const MouseEvent & e) | ||||
@@ -167,6 +167,7 @@ private: | |||||
double m_rec_pos = 0.0; | double m_rec_pos = 0.0; | ||||
bool m_lock_timesel_set = false; | bool m_lock_timesel_set = false; | ||||
bool m_using_audio_buffer = false; | bool m_using_audio_buffer = false; | ||||
bool m_is_at_selection_drag_area = false; | |||||
void updateCachedImage(); | void updateCachedImage(); | ||||
double viewXToNormalized(double xcor) | double viewXToNormalized(double xcor) | ||||
{ | { | ||||
@@ -8,10 +8,10 @@ Released under GNU General Public License v.2 license. | |||||
History : | History : | ||||
02-22-2018 1.0.2 | |||||
02-23-2018 1.0.2 | |||||
-Show approximate stretched output duration in info label (only valid if the stretch amount is not automated in the host) | -Show approximate stretched output duration in info label (only valid if the stretch amount is not automated in the host) | ||||
-Added stretch processing bypass parameter (to play the original sound looped like it is passed into the stretcher) | -Added stretch processing bypass parameter (to play the original sound looped like it is passed into the stretcher) | ||||
-Waveform selection can be moved by dragging with shift pressed | |||||
-Waveform selection can be moved by dragging the selection top area | |||||
-Smoothed playback with fades when changing waveform selection | -Smoothed playback with fades when changing waveform selection | ||||
-Fixes for the waveform graphics disappearing unexpectedly (this probably still isn't entirely fixed, though) | -Fixes for the waveform graphics disappearing unexpectedly (this probably still isn't entirely fixed, though) | ||||
02-16-2018 1.0.1 | 02-16-2018 1.0.1 | ||||