From 644d096f3cda41d050928879f370947740f751c5 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 7 Apr 2019 13:37:28 +1000 Subject: [PATCH] converted internal system to float --- effects/effect.cpp | 12 +- effects/effect.h | 16 ++- effects/internal/audionoiseeffect.cpp | 39 +++--- effects/internal/audionoiseeffect.h | 7 +- effects/internal/cornerpineffect.h | 2 +- effects/internal/crossdissolvetransition.h | 4 +- effects/internal/cubetransition.h | 4 +- .../internal/exponentialfadetransition.cpp | 43 +++--- effects/internal/exponentialfadetransition.h | 9 +- effects/internal/fillleftrighteffect.cpp | 11 +- effects/internal/fillleftrighteffect.h | 7 +- effects/internal/linearfadetransition.cpp | 34 +++-- effects/internal/linearfadetransition.h | 9 +- .../internal/logarithmicfadetransition.cpp | 33 +++-- effects/internal/logarithmicfadetransition.h | 9 +- effects/internal/paneffect.cpp | 30 +++-- effects/internal/paneffect.h | 7 +- effects/internal/richtexteffect.h | 2 +- effects/internal/shakeeffect.h | 4 +- effects/internal/solideffect.h | 2 +- effects/internal/texteffect.h | 2 +- effects/internal/timecodeeffect.h | 2 +- effects/internal/toneeffect.cpp | 44 ++++--- effects/internal/toneeffect.h | 7 +- effects/internal/transformeffect.h | 6 +- effects/internal/volumeeffect.cpp | 34 ++--- effects/internal/volumeeffect.h | 7 +- effects/internal/vsthost.cpp | 122 +++++++++++------- effects/internal/vsthost.h | 32 ++++- project/loadthread.cpp | 2 +- rendering/cacher.cpp | 80 +++++++----- 31 files changed, 365 insertions(+), 257 deletions(-) diff --git a/effects/effect.cpp b/effects/effect.cpp index 727bcff50..a7476f1dc 100644 --- a/effects/effect.cpp +++ b/effects/effect.cpp @@ -678,7 +678,7 @@ void Effect::load_from_string(const QByteArray &s) { for (int i=0;i -1) { @@ -1157,9 +1157,3 @@ const EffectMeta* get_meta_from_name(const QString& input) { } return nullptr; } - -qint16 mix_audio_sample(qint16 a, qint16 b) { - qint32 mixed_sample = static_cast(a) + static_cast(b); - mixed_sample = qMax(qMin(mixed_sample, static_cast(INT16_MAX)), static_cast(INT16_MIN)); - return static_cast(mixed_sample); -} diff --git a/effects/effect.h b/effects/effect.h index 47dec5629..95ec3500a 100644 --- a/effects/effect.h +++ b/effects/effect.h @@ -126,10 +126,6 @@ struct GLTextureCoords { float opacity; }; -const EffectMeta* get_meta_from_name(const QString& input); - -qint16 mix_audio_sample(qint16 a, qint16 b); - class Effect : public QObject { Q_OBJECT public: @@ -189,7 +185,7 @@ public: virtual void process_shader(double timecode, GLTextureCoords&, int iteration); virtual void process_coords(double timecode, GLTextureCoords& coords, int data); virtual GLuint process_superimpose(QOpenGLContext *ctx, double timecode); - virtual void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + virtual void process_audio(double timecode_start, double timecode_end, float **samples, int nb_samples, int nb_channels, int type); virtual void gizmo_draw(double timecode, GLTextureCoords& coords); void gizmo_move(EffectGizmo* sender, int x_movement, int y_movement, double timecode, bool done); @@ -205,8 +201,18 @@ public: return distribution(generator); } + template + T randomFloat() + { + static std::random_device device; + static std::mt19937 generator(device()); + static std::uniform_int_distribution<> distribution(-1.0, 1.0); + return distribution(generator); + } + static EffectPtr Create(Clip *c, const EffectMeta *em); static const EffectMeta* GetInternalMeta(int internal_id, int type); + static const EffectMeta* GetMetaFromName(const QString& input); public slots: void FieldChanged(); void SetEnabled(bool b); diff --git a/effects/internal/audionoiseeffect.cpp b/effects/internal/audionoiseeffect.cpp index 0e59d04b0..91194f1c0 100644 --- a/effects/internal/audionoiseeffect.cpp +++ b/effects/internal/audionoiseeffect.cpp @@ -35,30 +35,29 @@ AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em mix_val->SetValueAt(0, true); } -void AudioNoiseEffect::process_audio(double timecode_start, double timecode_end, quint8 *samples, int nb_bytes, int) { - double interval = (timecode_end - timecode_start)/nb_bytes; - for (int i=0;irandomNumber(); - qint16 right_noise_sample = this->randomNumber(); - // set noise volume - double vol = log_volume( amount_val->GetDoubleAt(timecode)*0.01 ); - left_noise_sample *= vol; - right_noise_sample *= vol; + float vol = log_volume( amount_val->GetDoubleAt(timecode)*0.01 ); - // mix with source audio - if (mix_val->GetBoolAt(timecode)) { - qint16 left_sample = static_cast (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF)); - qint16 right_sample = static_cast (((samples[i+3] & 0xFF) << 8) | (samples[i+2] & 0xFF)); - left_noise_sample = mix_audio_sample(left_noise_sample, left_sample); - right_noise_sample = mix_audio_sample(right_noise_sample, right_sample); + for (int j=0;jrandomFloat() * vol; + + // mix with source audio + if (mix_val->GetBoolAt(timecode)) { + samples[j][i] += noise_sample; + } else { + samples[j][i] = noise_sample; + } } - - samples[i+3] = static_cast (right_noise_sample >> 8); - samples[i+2] = static_cast (right_noise_sample); - samples[i+1] = static_cast (left_noise_sample >> 8); - samples[i] = static_cast (left_noise_sample); } } diff --git a/effects/internal/audionoiseeffect.h b/effects/internal/audionoiseeffect.h index 74c8ad9cd..819a02999 100644 --- a/effects/internal/audionoiseeffect.h +++ b/effects/internal/audionoiseeffect.h @@ -27,7 +27,12 @@ class AudioNoiseEffect : public Effect { Q_OBJECT public: AudioNoiseEffect(Clip* c, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; DoubleField* amount_val; BoolField* mix_val; diff --git a/effects/internal/cornerpineffect.h b/effects/internal/cornerpineffect.h index 3a2acc525..50ea31a95 100644 --- a/effects/internal/cornerpineffect.h +++ b/effects/internal/cornerpineffect.h @@ -26,7 +26,7 @@ class CornerPinEffect : public Effect { Q_OBJECT public: - CornerPinEffect(Clip* c, const EffectMeta* em); + CornerPinEffect(Clip* c, const EffectMeta* em); void process_coords(double timecode, GLTextureCoords& coords, int data); void process_shader(double timecode, GLTextureCoords& coords, int iterations); void gizmo_draw(double timecode, GLTextureCoords& coords); diff --git a/effects/internal/crossdissolvetransition.h b/effects/internal/crossdissolvetransition.h index 4d1e8f2c4..42afc7b93 100644 --- a/effects/internal/crossdissolvetransition.h +++ b/effects/internal/crossdissolvetransition.h @@ -25,8 +25,8 @@ class CrossDissolveTransition : public Transition { public: - CrossDissolveTransition(Clip *c, Clip *s, const EffectMeta* em); - void process_coords(double timecode, GLTextureCoords &, int data); + CrossDissolveTransition(Clip *c, Clip *s, const EffectMeta* em); + void process_coords(double timecode, GLTextureCoords &, int data); }; #endif // CROSSDISSOLVETRANSITION_H diff --git a/effects/internal/cubetransition.h b/effects/internal/cubetransition.h index f79280dec..a2c4da552 100644 --- a/effects/internal/cubetransition.h +++ b/effects/internal/cubetransition.h @@ -25,8 +25,8 @@ class CubeTransition : public Transition { public: - CubeTransition(Clip* c, Clip* s, const EffectMeta* em); - void process_coords(double timecode, GLTextureCoords &, int data); + CubeTransition(Clip* c, Clip* s, const EffectMeta* em); + void process_coords(double timecode, GLTextureCoords &, int data); }; #endif // CUBETRANSITION_H diff --git a/effects/internal/exponentialfadetransition.cpp b/effects/internal/exponentialfadetransition.cpp index 470964f86..292384b4d 100644 --- a/effects/internal/exponentialfadetransition.cpp +++ b/effects/internal/exponentialfadetransition.cpp @@ -24,32 +24,27 @@ ExponentialFadeTransition::ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {} -void ExponentialFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) { - double interval = (timecode_end-timecode_start)/nb_bytes; +void ExponentialFadeTransition::process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) { + double interval = (timecode_end-timecode_start)/nb_samples; - for (int i=0;i> 8); - samples[i] = (quint8) samp; } } diff --git a/effects/internal/exponentialfadetransition.h b/effects/internal/exponentialfadetransition.h index d2fadd73a..a9201f5dc 100644 --- a/effects/internal/exponentialfadetransition.h +++ b/effects/internal/exponentialfadetransition.h @@ -25,8 +25,13 @@ class ExponentialFadeTransition : public Transition { public: - ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; }; #endif // LINEARFADETRANSITION_H diff --git a/effects/internal/fillleftrighteffect.cpp b/effects/internal/fillleftrighteffect.cpp index 40e934c57..03fb4933c 100644 --- a/effects/internal/fillleftrighteffect.cpp +++ b/effects/internal/fillleftrighteffect.cpp @@ -30,9 +30,14 @@ FillLeftRightEffect::FillLeftRightEffect(Clip* c, const EffectMeta *em) : Effect fill_type->AddItem(tr("Fill Right with Left"), FILL_TYPE_RIGHT); } -void FillLeftRightEffect::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int) { - double interval = (timecode_end-timecode_start)/nb_bytes; - for (int i=0;iGetValueAt(timecode_start+(interval*i)) == FILL_TYPE_LEFT) { samples[i+1] = samples[i+3]; samples[i] = samples[i+2]; diff --git a/effects/internal/fillleftrighteffect.h b/effects/internal/fillleftrighteffect.h index 1eba500d3..64b126caa 100644 --- a/effects/internal/fillleftrighteffect.h +++ b/effects/internal/fillleftrighteffect.h @@ -27,7 +27,12 @@ class FillLeftRightEffect : public Effect { Q_OBJECT public: FillLeftRightEffect(Clip* c, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; private: ComboField* fill_type; }; diff --git a/effects/internal/linearfadetransition.cpp b/effects/internal/linearfadetransition.cpp index 0693874b6..ddb89d0af 100644 --- a/effects/internal/linearfadetransition.cpp +++ b/effects/internal/linearfadetransition.cpp @@ -22,22 +22,28 @@ LinearFadeTransition::LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {} -void LinearFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) { - double interval = (timecode_end-timecode_start)/nb_bytes; +void LinearFadeTransition::process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) { + double interval = (timecode_end-timecode_start)/nb_samples; - for (int i=0;i> 8); - samples[i] = (quint8) samp; } } diff --git a/effects/internal/linearfadetransition.h b/effects/internal/linearfadetransition.h index ed3fabd2f..abc5b7383 100644 --- a/effects/internal/linearfadetransition.h +++ b/effects/internal/linearfadetransition.h @@ -25,8 +25,13 @@ class LinearFadeTransition : public Transition { public: - LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; }; #endif // LINEARFADETRANSITION_H diff --git a/effects/internal/logarithmicfadetransition.cpp b/effects/internal/logarithmicfadetransition.cpp index 5012330fc..fe2f444ff 100644 --- a/effects/internal/logarithmicfadetransition.cpp +++ b/effects/internal/logarithmicfadetransition.cpp @@ -24,22 +24,27 @@ LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {} -void LogarithmicFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) { - double interval = (timecode_end-timecode_start)/nb_bytes; +void LogarithmicFadeTransition::process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) { + double interval = (timecode_end-timecode_start)/nb_samples; - for (int i=0;i> 8); - samples[i] = (quint8) samp; } } diff --git a/effects/internal/logarithmicfadetransition.h b/effects/internal/logarithmicfadetransition.h index 6983bcaf2..5cd03f57a 100644 --- a/effects/internal/logarithmicfadetransition.h +++ b/effects/internal/logarithmicfadetransition.h @@ -25,8 +25,13 @@ class LogarithmicFadeTransition : public Transition { public: - LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; }; #endif // LOGARITHMICFADETRANSITION_H diff --git a/effects/internal/paneffect.cpp b/effects/internal/paneffect.cpp index 0d85e8c9c..3902bef29 100644 --- a/effects/internal/paneffect.cpp +++ b/effects/internal/paneffect.cpp @@ -36,26 +36,30 @@ PanEffect::PanEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { pan_val->SetMaximum(100); } -void PanEffect::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int) { - double interval = (timecode_end - timecode_start)/nb_bytes; - for (int i=0;iGetDoubleAt(timecode_start+(interval*i)); double pval = log_volume(qAbs(pan_field_val)*0.01); - qint16 left_sample = qint16(((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF)); - qint16 right_sample = qint16(((samples[i+3] & 0xFF) << 8) | (samples[i+2] & 0xFF)); - if (pan_field_val < 0) { // affect right channel - right_sample *= (1.0-pval); + samples[1][i] *= (1.0-pval); } else { // affect left channel - left_sample *= (1.0-pval); + samples[0][i] *= (1.0-pval); } - - samples[i+3] = quint8(right_sample >> 8); - samples[i+2] = quint8(right_sample); - samples[i+1] = quint8(left_sample >> 8); - samples[i] = quint8(left_sample); } } diff --git a/effects/internal/paneffect.h b/effects/internal/paneffect.h index aac24dd6d..ac29d9e45 100644 --- a/effects/internal/paneffect.h +++ b/effects/internal/paneffect.h @@ -27,7 +27,12 @@ class PanEffect : public Effect { Q_OBJECT public: PanEffect(Clip* c, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; DoubleField* pan_val; }; diff --git a/effects/internal/richtexteffect.h b/effects/internal/richtexteffect.h index bdf484270..62c1ecb1b 100644 --- a/effects/internal/richtexteffect.h +++ b/effects/internal/richtexteffect.h @@ -27,7 +27,7 @@ class RichTextEffect : public Effect { Q_OBJECT public: RichTextEffect(Clip* c, const EffectMeta *em); - void redraw(double timecode); + virtual void redraw(double timecode) override; protected: virtual bool AlwaysUpdate() override; private: diff --git a/effects/internal/shakeeffect.h b/effects/internal/shakeeffect.h index fb0c56586..bed1ff55a 100644 --- a/effects/internal/shakeeffect.h +++ b/effects/internal/shakeeffect.h @@ -28,8 +28,8 @@ class ShakeEffect : public Effect { Q_OBJECT public: - ShakeEffect(Clip* c, const EffectMeta* em); - void process_coords(double timecode, GLTextureCoords& coords, int data); + ShakeEffect(Clip* c, const EffectMeta* em); + virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override; DoubleField* intensity_val; DoubleField* rotation_val; diff --git a/effects/internal/solideffect.h b/effects/internal/solideffect.h index d7220583a..a52977da9 100644 --- a/effects/internal/solideffect.h +++ b/effects/internal/solideffect.h @@ -35,7 +35,7 @@ public: }; SolidEffect(Clip* c, const EffectMeta *em); - virtual void redraw(double timecode); + virtual void redraw(double timecode) override; void SetType(SolidType type); private slots: diff --git a/effects/internal/texteffect.h b/effects/internal/texteffect.h index 2a0a136a6..857ea7ec9 100644 --- a/effects/internal/texteffect.h +++ b/effects/internal/texteffect.h @@ -30,7 +30,7 @@ class TextEffect : public Effect { Q_OBJECT public: TextEffect(Clip* c, const EffectMeta *em); - void redraw(double timecode); + virtual void redraw(double timecode) override; private slots: void outline_enable(bool); void shadow_enable(bool); diff --git a/effects/internal/timecodeeffect.h b/effects/internal/timecodeeffect.h index 4b5756fa0..743796199 100644 --- a/effects/internal/timecodeeffect.h +++ b/effects/internal/timecodeeffect.h @@ -30,7 +30,7 @@ class TimecodeEffect : public Effect { Q_OBJECT public: TimecodeEffect(Clip* c, const EffectMeta *em); - void redraw(double timecode); + virtual void redraw(double timecode) override; DoubleField* scale_val; ColorField* color_val; ColorField* color_bg_val; diff --git a/effects/internal/toneeffect.cpp b/effects/internal/toneeffect.cpp index f877083b6..c7b23e69c 100644 --- a/effects/internal/toneeffect.cpp +++ b/effects/internal/toneeffect.cpp @@ -49,29 +49,37 @@ ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_ mix_val->SetValueAt(0, true); } -void ToneEffect::process_audio(double timecode_start, double timecode_end, quint8 *samples, int nb_bytes, int) { - double interval = (timecode_end - timecode_start)/nb_bytes; - for (int i=0;iGetDoubleAt(timecode)) + /parent_clip->track()->sequence()->audio_frequency) + *log_volume(amount_val->GetDoubleAt(timecode)*0.01); - qint16 left_tone_sample = qint16(qRound(qSin((2*M_PI*sinX*freq_val->GetDoubleAt(timecode)) - /parent_clip->track()->sequence()->audio_frequency) - *log_volume(amount_val->GetDoubleAt(timecode)*0.01)*INT16_MAX)); - qint16 right_tone_sample = left_tone_sample; + for (int j=0;jGetBoolAt(timecode)) { + + // mix with source audio + samples[j][i] += tone_sample; + + } else { + + // replace source audio + samples[j][i] = tone_sample; + + } - // mix with source audio - if (mix_val->GetBoolAt(timecode)) { - qint16 left_sample = qint16(((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF)); - qint16 right_sample = qint16(((samples[i+3] & 0xFF) << 8) | (samples[i+2] & 0xFF)); - left_tone_sample = mix_audio_sample(left_tone_sample, left_sample); - right_tone_sample = mix_audio_sample(right_tone_sample, right_sample); } - samples[i+3] = quint8(right_tone_sample >> 8); - samples[i+2] = quint8(right_tone_sample); - samples[i+1] = quint8(left_tone_sample >> 8); - samples[i] = quint8(left_tone_sample); - sinX++; } } diff --git a/effects/internal/toneeffect.h b/effects/internal/toneeffect.h index 12e118201..396bb5806 100644 --- a/effects/internal/toneeffect.h +++ b/effects/internal/toneeffect.h @@ -27,7 +27,12 @@ class ToneEffect : public Effect { Q_OBJECT public: ToneEffect(Clip* c, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; ComboField* type_val; DoubleField* freq_val; diff --git a/effects/internal/transformeffect.h b/effects/internal/transformeffect.h index ba05c6614..42c840559 100644 --- a/effects/internal/transformeffect.h +++ b/effects/internal/transformeffect.h @@ -27,10 +27,10 @@ class TransformEffect : public Effect { Q_OBJECT public: TransformEffect(Clip* c, const EffectMeta* em); - void refresh(); - void process_coords(double timecode, GLTextureCoords& coords, int data); + virtual void refresh() override; + virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override; - void gizmo_draw(double timecode, GLTextureCoords& coords); + virtual void gizmo_draw(double timecode, GLTextureCoords& coords) override; public slots: void toggle_uniform_scale(bool enabled); private: diff --git a/effects/internal/volumeeffect.cpp b/effects/internal/volumeeffect.cpp index bccb4c496..d54a4d116 100644 --- a/effects/internal/volumeeffect.cpp +++ b/effects/internal/volumeeffect.cpp @@ -37,32 +37,22 @@ VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { volume_val->SetDisplayType(LabelSlider::Decibel); } -void VolumeEffect::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int) { - double interval = (timecode_end-timecode_start)/nb_bytes; - for (int i=0;iGetDoubleAt(timecode_start+(interval*i)); - qint32 right_samp = qint16(((samples[i+3] & 0xFF) << 8) | (samples[i+2] & 0xFF)); - qint32 left_samp = qint16(((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF)); + for (int j=0;j INT16_MAX) { - left_samp = INT16_MAX; - } else if (left_samp < INT16_MIN) { - left_samp = INT16_MIN; } - - if (right_samp > INT16_MAX) { - right_samp = INT16_MAX; - } else if (right_samp < INT16_MIN) { - right_samp = INT16_MIN; - } - - samples[i+3] = (quint8) (right_samp >> 8); - samples[i+2] = (quint8) right_samp; - samples[i+1] = (quint8) (left_samp >> 8); - samples[i] = (quint8) left_samp; } } diff --git a/effects/internal/volumeeffect.h b/effects/internal/volumeeffect.h index 2922d041e..c4a7a6180 100644 --- a/effects/internal/volumeeffect.h +++ b/effects/internal/volumeeffect.h @@ -27,7 +27,12 @@ class VolumeEffect : public Effect { Q_OBJECT public: VolumeEffect(Clip* c, const EffectMeta* em); - void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); + virtual void process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) override; DoubleField* volume_val; }; diff --git a/effects/internal/vsthost.cpp b/effects/internal/vsthost.cpp index a9f53e478..bbde8503a 100644 --- a/effects/internal/vsthost.cpp +++ b/effects/internal/vsthost.cpp @@ -46,7 +46,6 @@ class NSWindow; #endif #define BLOCK_SIZE 512 -#define CHANNEL_COUNT 2 struct VSTRect { int16_t top; @@ -212,15 +211,6 @@ bool VSTHost::canPluginDo(char *canDoString) { return (dispatcher(plugin, effCanDo, 0, 0, static_cast(canDoString), 0.0f) > 0); } -void VSTHost::processAudio(long numFrames) { - // Always reset the output array before processing. - for (int i=0;iprocessReplacing(plugin, inputs, outputs, numFrames); -} - void VSTHost::CreateDialogIfNull() { if (dialog == nullptr) { @@ -240,17 +230,12 @@ void VSTHost::send_data_cache_to_plugin() VSTHost::VSTHost(Clip* c, const EffectMeta *em) : Effect(c, em), plugin(nullptr), - dialog(nullptr) + dialog(nullptr), + input_cache(BLOCK_SIZE), + output_cache(BLOCK_SIZE) { plugin = nullptr; - inputs = new float* [CHANNEL_COUNT]; - outputs = new float* [CHANNEL_COUNT]; - for(int channel = 0; channel < CHANNEL_COUNT; channel++) { - inputs[channel] = new float[BLOCK_SIZE]; - outputs[channel] = new float[BLOCK_SIZE]; - } - EffectRow* file_row = new EffectRow(this, tr("Plugin"), true, false); file_field = new FileField(file_row, "filename"); connect(file_field, SIGNAL(Changed()), this, SLOT(change_plugin()), Qt::QueuedConnection); @@ -264,47 +249,35 @@ VSTHost::VSTHost(Clip* c, const EffectMeta *em) : } VSTHost::~VSTHost() { - for(int channel = 0; channel < CHANNEL_COUNT; channel++) { - delete [] inputs[channel]; - delete [] outputs[channel]; - } - delete [] outputs; - delete [] inputs; - freePlugin(); } -void VSTHost::process_audio(double, double, quint8* samples, int nb_bytes, int) { +void VSTHost::process_audio(double timecode_start, + double timecode_end, + float **samples, + int nb_samples, + int channel_count, + int type) { if (plugin != nullptr) { - int interval = BLOCK_SIZE*4; - for (int i=0;i>2; - inputs[0][index] = float(left_sample) / float(INT16_MAX); - inputs[1][index] = float(right_sample) / float(INT16_MAX); + for (int i=0;i>2); + plugin->processReplacing(plugin, input_cache.data(), output_cache.data(), sample_size); - // convert back to int16 - for (int j=i;j>2; - - qint16 left_sample = qint16(qRound(outputs[0][index] * INT16_MAX)); - qint16 right_sample = qint16(qRound(outputs[1][index] * INT16_MAX)); - - samples[j+3] = quint8(right_sample >> 8); - samples[j+2] = quint8(right_sample); - samples[j+1] = quint8(left_sample >> 8); - samples[j] = quint8(left_sample); + // Copy output cache back to samples + for (int j=0;jSetEnabled(plugin != nullptr); } + +SampleCache::SampleCache(int block_size) : + block_size_(block_size), + channel_count_(0), + array_(nullptr) +{ +} + +SampleCache::~SampleCache() +{ + destroy(); +} + +void SampleCache::Create(int channels) +{ + if (channel_count_ != channels) { + + if (channel_count_ > 0) { + destroy(); + } + + channel_count_ = channels; + + array_ = new float* [channel_count_]; + for (int i=0;i> 1) / nb_channels / sample_rate); +double samples_to_seconds(int nb_samples, int nb_channels, int sample_rate) { + return (double(nb_samples) / double(nb_channels) / double(sample_rate)); } -void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int nb_bytes, QVector nests) { +int samples_to_bytes(int nb_samples, int nb_channels) { + return nb_samples * nb_channels * sizeof(float); +} + +void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int nb_samples, int nb_channels, QVector nests) { // perform all audio effects double timecode_end; - timecode_end = timecode_start + bytes_to_seconds(nb_bytes, frame->channels, frame->sample_rate); + timecode_end = timecode_start + samples_to_seconds(nb_samples, frame->channels, frame->sample_rate); for (int j=0;jeffects.size();j++) { Effect* e = clip->effects.at(j).get(); if (e->IsEnabled()) { - e->process_audio(timecode_start, timecode_end, frame->data[0], nb_bytes, 2); + e->process_audio(timecode_start, timecode_end, reinterpret_cast(frame->data), nb_samples, nb_channels, kTransitionNone); } } if (clip->opening_transition != nullptr) { @@ -71,7 +75,7 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int double adjustment = transition_end - transition_start; double adjusted_range_start = (timecode_start - transition_start) / adjustment; double adjusted_range_end = (timecode_end - transition_start) / adjustment; - clip->opening_transition->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionOpening); + clip->opening_transition->process_audio(adjusted_range_start, adjusted_range_end, reinterpret_cast(frame->data), nb_samples, nb_channels, kTransitionOpening); } } } @@ -84,7 +88,7 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int double adjustment = transition_end - transition_start; double adjusted_range_start = (timecode_start - transition_start) / adjustment; double adjusted_range_end = (timecode_end - transition_start) / adjustment; - clip->closing_transition->process_audio(adjusted_range_start, adjusted_range_end, frame->data[0], nb_bytes, kTransitionClosing); + clip->closing_transition->process_audio(adjusted_range_start, adjusted_range_end, reinterpret_cast(frame->data), nb_samples, nb_channels, kTransitionClosing); } } } @@ -95,7 +99,8 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int apply_audio_effects(next_nest, timecode_start + (double(clip->timeline_in(true)-clip->clip_in(true))/clip->track()->sequence()->frame_rate), frame, - nb_bytes, + nb_samples, + nb_channels, nests); } } @@ -157,16 +162,16 @@ void Cacher::CacheAudioWorker() { while (true) { AVFrame* frame; - int nb_bytes = INT_MAX; + int nb_samples = INT_MAX; if (clip->media() == nullptr) { frame = frame_; - nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; - while ((frame_sample_index_ == -1 || frame_sample_index_ >= nb_bytes) && nb_bytes > 0) { + nb_samples = frame->nb_samples; + while ((frame_sample_index_ == -1 || frame_sample_index_ >= nb_samples) && nb_samples > 0) { // create "new frame" - memset(frame_->data[0], 0, nb_bytes); - apply_audio_effects(clip, bytes_to_seconds(frame->pts, frame->channels, frame->sample_rate), frame, nb_bytes, nests_); - frame_->pts += nb_bytes; + memset(frame_->data[0], 0, nb_samples); + apply_audio_effects(clip, samples_to_seconds(frame->pts, frame->channels, frame->sample_rate), frame, nb_samples, frame->channels, nests_); + frame_->pts += nb_samples; frame_sample_index_ = 0; if (audio_buffer_write == 0) { audio_buffer_write = get_buffer_offset_from_frame(last_fr, qMax(timeline_in, target_frame)); @@ -184,7 +189,7 @@ void Cacher::CacheAudioWorker() { // retrieve frame bool new_frame = false; - while ((frame_sample_index_ == -1 || frame_sample_index_ >= nb_bytes) && nb_bytes > 0) { + while ((frame_sample_index_ == -1 || frame_sample_index_ >= nb_samples) && nb_samples > 0) { // no more audio left in frame, get a new one if (!reached_end) { @@ -338,10 +343,10 @@ void Cacher::CacheAudioWorker() { if (frame_sample_index_ < 0) { frame_sample_index_ = 0; } else { - frame_sample_index_ -= nb_bytes; + frame_sample_index_ -= nb_samples; } - nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; + nb_samples = frame->nb_samples; if (audio_just_reset) { // get precise sample offset for the elected clip_in from this audio frame @@ -356,7 +361,7 @@ void Cacher::CacheAudioWorker() { dout << "fsts:" << frame_sts << "tsts:" << target_sts << "nbs:" << nb_samples << "nbb:" << nb_bytes << "rev_targetToSec:" << (reverse_target * timebase); dout << "fsi-calc:" << frame_sample_index; #endif - if (reverse_audio) frame_sample_index_ = nb_bytes - frame_sample_index_; + if (reverse_audio) frame_sample_index_ = nb_samples - frame_sample_index_; audio_just_reset = false; } @@ -393,9 +398,19 @@ void Cacher::CacheAudioWorker() { #endif // apply any audio effects to the data - if (nb_bytes == INT_MAX) nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast(frame->format)) * frame->channels; + if (nb_samples == INT_MAX) { + nb_samples = frame->nb_samples; + } if (new_frame) { - apply_audio_effects(clip, bytes_to_seconds(audio_buffer_write, 2, current_audio_freq()) + audio_ibuffer_timecode + ((double)clip->clip_in(true)/clip->track()->sequence()->frame_rate) - ((double)timeline_in/last_fr), frame, nb_bytes, nests_); + apply_audio_effects(clip, + samples_to_seconds(audio_buffer_write, 2, current_audio_freq()) + + audio_ibuffer_timecode + + (double(clip->clip_in(true))/clip->track()->sequence()->frame_rate) + - (double(timeline_in)/last_fr), + frame, + nb_samples, + frame->channels, + nests_); } } @@ -408,23 +423,20 @@ void Cacher::CacheAudioWorker() { audio_write_lock.lock(); int sample_skip = 4*qMax(0, qAbs(playback_speed_)-1); - int sample_byte_size = av_get_bytes_per_sample(static_cast(frame->format)); - while (frame_sample_index_ < nb_bytes + while (frame_sample_index_ < nb_samples && audio_buffer_write < audio_ibuffer_read+(audio_ibuffer_size>>1) && audio_buffer_write < buffer_timeline_out) { for (int i=0;ichannels;i++) { - int upper_byte_index = (audio_buffer_write+1)%audio_ibuffer_size; - int lower_byte_index = (audio_buffer_write)%audio_ibuffer_size; - qint16 old_sample = static_cast((audio_ibuffer[upper_byte_index] & 0xFF) << 8 | (audio_ibuffer[lower_byte_index] & 0xFF)); - qint16 new_sample = static_cast((frame->data[0][frame_sample_index_+1] & 0xFF) << 8 | (frame->data[0][frame_sample_index_] & 0xFF)); - qint16 mixed_sample = mix_audio_sample(old_sample, new_sample); + int buffer_index = audio_buffer_write%audio_ibuffer_size; + int frame_index = frame_sample_index_ * sizeof(float); - audio_ibuffer[upper_byte_index] = quint8((mixed_sample >> 8) & 0xFF); - audio_ibuffer[lower_byte_index] = quint8(mixed_sample & 0xFF); - - audio_buffer_write+=sample_byte_size; - frame_sample_index_+=sample_byte_size; + audio_ibuffer[buffer_index] += static_cast((frame->data[0][frame_index+3] & 0xFF) << 24 + | (frame->data[0][frame_index+2] & 0xFF) << 16 + | (frame->data[0][frame_index+1] & 0xFF) << 8 + | (frame->data[0][frame_index] & 0xFF)); + audio_buffer_write++; + frame_sample_index_++; } frame_sample_index_ += sample_skip; @@ -444,7 +456,7 @@ void Cacher::CacheAudioWorker() { if (audio_thread != nullptr) audio_thread->notifyReceiver(); } - if (frame_sample_index_ >= nb_bytes) { + if (frame_sample_index_ >= nb_samples) { frame_sample_index_ = -1; } else { // assume we have no more data to send