Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EngineMaster: Use mixxx::audio::SampleRate #4183

Merged
merged 1 commit into from
Aug 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 58 additions & 42 deletions src/engine/enginemaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ const CSAMPLE* EngineMaster::getSidechainBuffer() const {

void EngineMaster::processChannels(int iBufferSize) {
// Update internal sync lock rate.
m_pMasterSync->onCallbackStart(m_iSampleRate, m_iBufferSize);
m_pMasterSync->onCallbackStart(m_sampleRate, m_iBufferSize);

m_activeBusChannels[EngineChannel::LEFT].clear();
m_activeBusChannels[EngineChannel::CENTER].clear();
Expand Down Expand Up @@ -372,7 +372,7 @@ void EngineMaster::processChannels(int iBufferSize) {
// Note, because we call this on the internal clock first,
// it will have an up-to-date beatDistance, whereas the other
// Syncables will not.
m_pMasterSync->onCallbackEnd(m_iSampleRate, m_iBufferSize);
m_pMasterSync->onCallbackEnd(m_sampleRate, m_iBufferSize);

// After all the engines have been processed, trigger post-processing
// which ensures that all channels are updating certain values at the
Expand All @@ -396,7 +396,7 @@ void EngineMaster::process(const int iBufferSize) {
bool boothEnabled = m_pBoothEnabled->toBool();
bool headphoneEnabled = m_pHeadphoneEnabled->toBool();

m_iSampleRate = static_cast<int>(m_pMasterSampleRate->get());
m_sampleRate = mixxx::audio::SampleRate::fromDouble(m_pMasterSampleRate->get());
m_iBufferSize = iBufferSize;
// TODO: remove assumption of stereo buffer
const unsigned int kChannels = 2;
Expand Down Expand Up @@ -428,12 +428,14 @@ void EngineMaster::process(const int iBufferSize) {
// Process effects and mix PFL channels together for the headphones.
// Effects will be reprocessed post-fader for the crossfader buses
// and master mix, so the channel input buffers cannot be modified here.
ChannelMixer::applyEffectsAndMixChannels(
m_headphoneGain, &m_activeHeadphoneChannels,
&m_channelHeadphoneGainCache,
m_pHead, m_headphoneHandle.handle(),
m_iBufferSize, m_iSampleRate,
m_pEngineEffectsManager);
ChannelMixer::applyEffectsAndMixChannels(m_headphoneGain,
&m_activeHeadphoneChannels,
&m_channelHeadphoneGainCache,
m_pHead,
m_headphoneHandle.handle(),
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
uklotzde marked this conversation as resolved.
Show resolved Hide resolved
m_pEngineEffectsManager);

// Process headphone channel effects
if (m_pEngineEffectsManager) {
Expand All @@ -448,21 +450,25 @@ void EngineMaster::process(const int iBufferSize) {
headphoneFeatures = m_activeHeadphoneChannels.at(0)->m_features;
}
m_pEngineEffectsManager->processPostFaderInPlace(
m_headphoneHandle.handle(),
m_headphoneHandle.handle(),
m_pHead,
m_iBufferSize, m_iSampleRate,
headphoneFeatures);
m_headphoneHandle.handle(),
m_headphoneHandle.handle(),
m_pHead,
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
headphoneFeatures);
}
}

// Mix all the talkover enabled channels together.
// Effects processing is done in place to avoid unnecessary buffer copying.
ChannelMixer::applyEffectsInPlaceAndMixChannels(
m_talkoverGain, &m_activeTalkoverChannels,
ChannelMixer::applyEffectsInPlaceAndMixChannels(m_talkoverGain,
&m_activeTalkoverChannels,
&m_channelTalkoverGainCache,
m_pTalkover, m_masterHandle.handle(),
m_iBufferSize, m_iSampleRate, m_pEngineEffectsManager);
m_pTalkover,
m_masterHandle.handle(),
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
m_pEngineEffectsManager);

// Process effects on all microphones mixed together
// We have no metadata for mixed effect buses, so use an empty GroupFeatureState.
Expand All @@ -473,7 +479,7 @@ void EngineMaster::process(const int iBufferSize) {
m_masterHandle.handle(),
m_pTalkover,
m_iBufferSize,
m_iSampleRate,
static_cast<int>(m_sampleRate.value()),
busFeatures);
}

Expand Down Expand Up @@ -511,31 +517,39 @@ void EngineMaster::process(const int iBufferSize) {
m_pTalkoverDucking->getGain(m_iBufferSize / 2));

for (int o = EngineChannel::LEFT; o <= EngineChannel::RIGHT; o++) {
ChannelMixer::applyEffectsInPlaceAndMixChannels(
m_masterGain,
&m_activeBusChannels[o],
&m_channelMasterGainCache, // no [o] because the old gain follows an orientation switch
m_pOutputBusBuffers[o], m_masterHandle.handle(),
m_iBufferSize, m_iSampleRate, m_pEngineEffectsManager);
ChannelMixer::applyEffectsInPlaceAndMixChannels(m_masterGain,
&m_activeBusChannels[o],
&m_channelMasterGainCache, // no [o] because the old gain follows an orientation switch
m_pOutputBusBuffers[o],
m_masterHandle.handle(),
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
m_pEngineEffectsManager);
}

// Process crossfader orientation bus channel effects
if (m_pEngineEffectsManager) {
m_pEngineEffectsManager->processPostFaderInPlace(
m_busCrossfaderLeftHandle.handle(),
m_masterHandle.handle(),
m_pOutputBusBuffers[EngineChannel::LEFT],
m_iBufferSize, m_iSampleRate, busFeatures);
m_busCrossfaderLeftHandle.handle(),
m_masterHandle.handle(),
m_pOutputBusBuffers[EngineChannel::LEFT],
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
busFeatures);
m_pEngineEffectsManager->processPostFaderInPlace(
m_busCrossfaderCenterHandle.handle(),
m_masterHandle.handle(),
m_pOutputBusBuffers[EngineChannel::CENTER],
m_iBufferSize, m_iSampleRate, busFeatures);
m_busCrossfaderCenterHandle.handle(),
m_masterHandle.handle(),
m_pOutputBusBuffers[EngineChannel::CENTER],
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
busFeatures);
m_pEngineEffectsManager->processPostFaderInPlace(
m_busCrossfaderRightHandle.handle(),
m_masterHandle.handle(),
m_pOutputBusBuffers[EngineChannel::RIGHT],
m_iBufferSize, m_iSampleRate, busFeatures);
m_busCrossfaderRightHandle.handle(),
m_masterHandle.handle(),
m_pOutputBusBuffers[EngineChannel::RIGHT],
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
busFeatures);
}

if (masterEnabled) {
Expand Down Expand Up @@ -705,7 +719,8 @@ void EngineMaster::process(const int iBufferSize) {
m_masterOutputHandle.handle(),
m_masterHandle.handle(),
m_pMaster,
m_iBufferSize, m_iSampleRate,
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
masterFeatures);
}

Expand Down Expand Up @@ -761,10 +776,11 @@ void EngineMaster::applyMasterEffects() {
masterFeatures.has_gain = true;
masterFeatures.gain = m_pMasterGain->get();
m_pEngineEffectsManager->processPostFaderInPlace(m_masterHandle.handle(),
m_masterHandle.handle(),
m_pMaster,
m_iBufferSize, m_iSampleRate,
masterFeatures);
m_masterHandle.handle(),
m_pMaster,
m_iBufferSize,
static_cast<int>(m_sampleRate.value()),
masterFeatures);
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/engine/enginemaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
#include <QObject>
#include <QVarLengthArray>

#include "preferences/usersettings.h"
#include "audio/types.h"
#include "control/controlobject.h"
#include "control/controlpushbutton.h"
#include "engine/engineobject.h"
#include "engine/channels/enginechannel.h"
#include "engine/channelhandle.h"
#include "engine/channels/enginechannel.h"
#include "engine/engineobject.h"
#include "preferences/usersettings.h"
#include "recording/recordingmanager.h"
#include "soundio/soundmanager.h"
#include "soundio/soundmanagerutil.h"
#include "recording/recordingmanager.h"

class EngineWorkerScheduler;
class EngineBuffer;
Expand Down Expand Up @@ -283,7 +284,7 @@ class EngineMaster : public QObject, public AudioSource {
QVarLengthArray<ChannelInfo*, kPreallocatedChannels> m_activeHeadphoneChannels;
QVarLengthArray<ChannelInfo*, kPreallocatedChannels> m_activeTalkoverChannels;

unsigned int m_iSampleRate;
mixxx::audio::SampleRate m_sampleRate;
unsigned int m_iBufferSize;

// Mixing buffers for each output.
Expand Down
4 changes: 2 additions & 2 deletions src/engine/sync/enginesync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,11 +527,11 @@ void EngineSync::addSyncableDeck(Syncable* pSyncable) {
m_syncables.append(pSyncable);
}

void EngineSync::onCallbackStart(int sampleRate, int bufferSize) {
void EngineSync::onCallbackStart(mixxx::audio::SampleRate sampleRate, int bufferSize) {
m_pInternalClock->onCallbackStart(sampleRate, bufferSize);
}

void EngineSync::onCallbackEnd(int sampleRate, int bufferSize) {
void EngineSync::onCallbackEnd(mixxx::audio::SampleRate sampleRate, int bufferSize) {
m_pInternalClock->onCallbackEnd(sampleRate, bufferSize);
}

Expand Down
5 changes: 3 additions & 2 deletions src/engine/sync/enginesync.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <gtest/gtest_prod.h>

#include "audio/types.h"
#include "engine/sync/syncable.h"
#include "preferences/usersettings.h"

Expand Down Expand Up @@ -57,8 +58,8 @@ class EngineSync : public SyncableListener {

void addSyncableDeck(Syncable* pSyncable);
EngineChannel* getLeader() const;
void onCallbackStart(int sampleRate, int bufferSize);
void onCallbackEnd(int sampleRate, int bufferSize);
void onCallbackStart(mixxx::audio::SampleRate sampleRate, int bufferSize);
void onCallbackEnd(mixxx::audio::SampleRate sampleRate, int bufferSize);

private:
/// Iterate over decks, and based on sync and play status, pick a new Leader.
Expand Down
18 changes: 9 additions & 9 deletions src/engine/sync/internalclock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ InternalClock::InternalClock(const QString& group, SyncableListener* pEngineSync
: m_group(group),
m_pEngineSync(pEngineSync),
m_mode(SyncMode::None),
m_iOldSampleRate(44100),
m_oldSampleRate(mixxx::audio::SampleRate{44100}),
m_oldBpm(kDefaultBpm),
m_baseBpm(kDefaultBpm),
m_dBeatLength(m_iOldSampleRate * 60.0 / m_oldBpm.value()),
m_dBeatLength(m_oldSampleRate * 60.0 / m_oldBpm.value()),
m_dClockPosition(0) {
// Pick a wide range (1 to 200) and allow out of bounds sets. This lets you
// map a soft-takeover MIDI knob to the leader BPM. This also creates bpm_up
Expand Down Expand Up @@ -132,7 +132,7 @@ void InternalClock::updateLeaderBpm(mixxx::Bpm bpm) {
return;
}
m_pClockBpm->set(bpm.value());
updateBeatLength(m_iOldSampleRate, bpm);
updateBeatLength(m_oldSampleRate, bpm);
}

void InternalClock::updateInstantaneousBpm(mixxx::Bpm bpm) {
Expand Down Expand Up @@ -160,7 +160,7 @@ void InternalClock::reinitLeaderParams(double beatDistance, mixxx::Bpm baseBpm,

void InternalClock::slotBpmChanged(double bpm) {
m_baseBpm = mixxx::Bpm(bpm);
updateBeatLength(m_iOldSampleRate, m_baseBpm);
updateBeatLength(m_oldSampleRate, m_baseBpm);
if (!isSynchronized()) {
return;
}
Expand All @@ -177,8 +177,8 @@ void InternalClock::slotBeatDistanceChanged(double beatDistance) {
updateLeaderBeatDistance(beatDistance);
}

void InternalClock::updateBeatLength(int sampleRate, mixxx::Bpm bpm) {
if (m_iOldSampleRate == sampleRate && bpm == m_oldBpm) {
void InternalClock::updateBeatLength(mixxx::audio::SampleRate sampleRate, mixxx::Bpm bpm) {
if (m_oldSampleRate == sampleRate && bpm == m_oldBpm) {
return;
}

Expand Down Expand Up @@ -207,19 +207,19 @@ void InternalClock::updateBeatLength(int sampleRate, mixxx::Bpm bpm) {
}
}

m_iOldSampleRate = sampleRate;
m_oldSampleRate = sampleRate;

// Restore the old beat distance.
updateLeaderBeatDistance(oldBeatDistance);
}

void InternalClock::onCallbackStart(int sampleRate, int bufferSize) {
void InternalClock::onCallbackStart(mixxx::audio::SampleRate sampleRate, int bufferSize) {
Q_UNUSED(sampleRate)
Q_UNUSED(bufferSize)
m_pEngineSync->notifyInstantaneousBpmChanged(this, getBpm());
}

void InternalClock::onCallbackEnd(int sampleRate, int bufferSize) {
void InternalClock::onCallbackEnd(mixxx::audio::SampleRate sampleRate, int bufferSize) {
updateBeatLength(sampleRate, getBpm());

// stereo samples, so divide by 2
Expand Down
11 changes: 6 additions & 5 deletions src/engine/sync/internalclock.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#pragma once

#include <QObject>
#include <QString>
#include <QScopedPointer>
#include <QString>

#include "audio/types.h"
#include "engine/sync/clock.h"
#include "engine/sync/syncable.h"

Expand Down Expand Up @@ -57,16 +58,16 @@ class InternalClock : public QObject, public Clock, public Syncable {
void updateInstantaneousBpm(mixxx::Bpm bpm) override;
void reinitLeaderParams(double beatDistance, mixxx::Bpm baseBpm, mixxx::Bpm bpm) override;

void onCallbackStart(int sampleRate, int bufferSize);
void onCallbackEnd(int sampleRate, int bufferSize);
void onCallbackStart(mixxx::audio::SampleRate sampleRate, int bufferSize);
void onCallbackEnd(mixxx::audio::SampleRate sampleRate, int bufferSize);

private slots:
void slotBpmChanged(double bpm);
void slotBeatDistanceChanged(double beatDistance);
void slotSyncLeaderEnabledChangeRequest(double state);

private:
void updateBeatLength(int sampleRate, mixxx::Bpm bpm);
void updateBeatLength(mixxx::audio::SampleRate sampleRate, mixxx::Bpm bpm);

const QString m_group;
SyncableListener* m_pEngineSync;
Expand All @@ -75,7 +76,7 @@ class InternalClock : public QObject, public Clock, public Syncable {
QScopedPointer<ControlPushButton> m_pSyncLeaderEnabled;
SyncMode m_mode;

int m_iOldSampleRate;
mixxx::audio::SampleRate m_oldSampleRate;
mixxx::Bpm m_oldBpm;

// This is the BPM value at unity adopted when sync is enabled.
Expand Down