Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
746c194
Allow SounddeviceNetwork to be clock reference device.
daschuer Dec 16, 2015
a72cba4
force networkdevice as clock reference
daschuer Feb 3, 2016
56a8166
Merge remote-tracking branch 'upstream/master' into networkclockref
daschuer Feb 4, 2016
d9c4170
use mixxx::Duration
daschuer Feb 6, 2016
a117ec9
Latency usage calculation fixed
daschuer Feb 7, 2016
2ad8a24
set master timing COs
daschuer Feb 7, 2016
035abf8
improve andling of target time
daschuer Feb 7, 2016
29d1e2d
stop clock ref thread
daschuer Feb 7, 2016
f4ad419
Move underflow monitoring to SoundManager
daschuer Feb 13, 2016
f99b605
prevent m_outputFifo overflow
daschuer Feb 13, 2016
251dc46
m_pSoundManager->underflowHappened() with debug code to identify callers
daschuer Feb 13, 2016
d2ca9c4
Ensure that m_inputFifo is filled with a half chunk extra.
daschuer Feb 13, 2016
75bdf20
Tweak buffer settings for start up
daschuer Feb 14, 2016
1c3d250
UnderflowHappened Warning only in developer mode
daschuer Feb 14, 2016
46f18f1
Add preferences option to force using network clock
daschuer Feb 14, 2016
5cadcc7
respect new force network clock option in sound manager
daschuer Feb 14, 2016
2bd0110
connect settingsChanged slot
daschuer Feb 14, 2016
c00c2be
Init input fifo to with one chunk
daschuer Feb 15, 2016
b52560c
Improve use >= to detect write underflows
daschuer Feb 16, 2016
42683a1
Merge branch 'master' into networkclockref
daschuer Jun 24, 2016
34f6a0f
Merge remote-tracking branch 'upstream/master' into networkclockref
daschuer Feb 13, 2017
077d68c
Use std:unique_ptr
daschuer Feb 13, 2017
5588ac7
Use SINT as sample index in SoundDevice
daschuer Feb 13, 2017
d2ad4db
Fix segfault due to bug in drift correction
daschuer Feb 13, 2017
3f3a28c
Merge remote-tracking branch 'upstream/master' into networkclockref
daschuer Jul 26, 2017
ff0abf3
Merge remote-tracking branch 'upstream/master' into networkclockref
daschuer Nov 18, 2017
ee6b3bd
fix typos
daschuer Nov 19, 2017
9772814
Comment why engine warnings are disabled
daschuer Nov 19, 2017
f125231
Improved engine clock tooltip
daschuer Nov 19, 2017
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
25 changes: 25 additions & 0 deletions src/preferences/dialog/dlgprefsound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent, SoundManager* pSoundManager,
connect(deviceSyncComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(syncBuffersChanged(int)));

engineClockComboBox->clear();
engineClockComboBox->addItem(tr("Soundcard Clock"));
engineClockComboBox->addItem(tr("Network Clock"));
engineClockComboBox->setCurrentIndex(0);
connect(engineClockComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(engineClockChanged(int)));

keylockComboBox->clear();
for (int i = 0; i < EngineBuffer::KEYLOCK_ENGINE_COUNT; ++i) {
keylockComboBox->addItem(
Expand Down Expand Up @@ -126,6 +133,8 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent, SoundManager* pSoundManager,
this, SLOT(settingChanged()));
connect(deviceSyncComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(settingChanged()));
connect(engineClockComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(settingChanged()));
connect(keylockComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(settingChanged()));

Expand Down Expand Up @@ -398,6 +407,12 @@ void DlgPrefSound::loadSettings(const SoundManagerConfig &config) {
deviceSyncComboBox->setCurrentIndex(0);
}

if (m_config.getForceNetworkClock()) {
engineClockComboBox->setCurrentIndex(1);
} else {
engineClockComboBox->setCurrentIndex(0);
}

// Default keylock is Rubberband.
int keylock_engine = m_pConfig->getValue(
ConfigKey("[Master]", "keylock_engine"), 1);
Expand Down Expand Up @@ -486,6 +501,16 @@ void DlgPrefSound::syncBuffersChanged(int index) {
}
}

void DlgPrefSound::engineClockChanged(int index) {
if (index == 0) {
// "Soundcard Clock"
m_config.setForceNetworkClock(false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this take effect only after the Apply button is pressed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, or the OK button.

} else {
// "Network Clock"
m_config.setForceNetworkClock(true);
}
}

// Slot called whenever the selected sample rate is changed. Populates the
// audio buffer input box with SMConfig::kMaxLatency values, starting at 1ms,
// representing a number of frames per buffer, which will always be a power
Expand Down
1 change: 1 addition & 0 deletions src/preferences/dialog/dlgprefsound.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class DlgPrefSound : public DlgPreferencePage, public Ui::DlgPrefSoundDlg {
void audioBufferChanged(int index);
void updateAudioBufferSizes(int sampleRateIndex);
void syncBuffersChanged(int index);
void engineClockChanged(int index);
void refreshDevices();
void settingChanged();
void deviceSettingChanged();
Expand Down
46 changes: 30 additions & 16 deletions src/preferences/dialog/dlgprefsounddlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@
<widget class="QComboBox" name="deviceSyncComboBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="engineClockLabel">
<property name="text">
<string>Engine Clock</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="engineClockComboBox">
<property name="toolTip">
<string>Use soundcard clock for live audience setups and lowest latency.&lt;br&gt;Use network clock for broadcasting without a live audience.</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="keylockLabel">
<property name="text">
<string>Keylock/Pitch-Bending Engine</string>
Expand All @@ -76,46 +90,46 @@
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="masterMixComboBox"/>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="keylockComboBox"/>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="masteMixLabel">
<property name="text">
<string>Master Mix</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="masterMixComboBox"/>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="masterOutputModeComboBox"/>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="masterMonoLabel">
<property name="text">
<string>Master Output Mode</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QComboBox" name="micMonitorModeComboBox"/>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="micMonitorModeLabel">
<property name="text">
<string>Microphone Monitor Mode</string>
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="latencyCompensationLabel">
<property name="text">
<string>Microphone Latency Compensation</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QDoubleSpinBox" name="latencyCompensationSpinBox">
<property name="suffix">
<string> ms</string>
Expand All @@ -131,14 +145,14 @@
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QLabel" name="masterDelayLabel">
<property name="text">
<string>Master Delay</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" column="1">
<widget class="QDoubleSpinBox" name="masterDelaySpinBox">
<property name="suffix">
<string extracomment="milliseconds"> ms</string>
Expand All @@ -154,14 +168,14 @@
</property>
</widget>
</item>
<item row="11" column="0">
<item row="12" column="0">
<widget class="QLabel" name="headDelayLabel">
<property name="text">
<string>Headphone Delay</string>
</property>
</widget>
</item>
<item row="11" column="1">
<item row="12" column="1">
<widget class="QDoubleSpinBox" name="headDelaySpinBox">
<property name="suffix">
<string extracomment="milliseconds"> ms</string>
Expand All @@ -177,14 +191,14 @@
</property>
</widget>
</item>
<item row="12" column="0">
<item row="13" column="0">
<widget class="QLabel" name="boothDelayLabel">
<property name="text">
<string>Booth Delay</string>
</property>
</widget>
</item>
<item row="12" column="1">
<item row="13" column="1">
<widget class="QDoubleSpinBox" name="boothDelaySpinBox">
<property name="suffix">
<string extracomment="milliseconds"> ms</string>
Expand All @@ -200,7 +214,7 @@
</property>
</widget>
</item>
<item row="9" column="0" colspan="2">
<item row="14" column="0" colspan="2">
<widget class="QLabel" name="latencyCompensationWarningLabel">
<property name="text">
<string notr="true">warning goes here</string>
Expand Down
35 changes: 17 additions & 18 deletions src/soundio/sounddevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ bool SoundDevice::operator==(const QString &other) const {
}

void SoundDevice::composeOutputBuffer(CSAMPLE* outputBuffer,
const unsigned int framesToCompose,
const unsigned int framesReadOffset,
const unsigned int iFrameSize) {
const SINT framesToCompose,
const SINT framesReadOffset,
const int iFrameSize) {
//qDebug() << "SoundDevice::composeOutputBuffer()"
// << device->getInternalName()
// << framesToCompose << iFrameSize;
Expand Down Expand Up @@ -149,20 +149,20 @@ void SoundDevice::composeOutputBuffer(CSAMPLE* outputBuffer,
if (iChannelCount == 1) {
// All AudioOutputs are stereo as of Mixxx 1.12.0. If we have a mono
// output then we need to downsample.
for (unsigned int iFrameNo = 0; iFrameNo < framesToCompose; ++iFrameNo) {
for (SINT iFrameNo = 0; iFrameNo < framesToCompose; ++iFrameNo) {
// iFrameBase is the "base sample" in a frame (ie. the first
// sample in a frame)
const unsigned int iFrameBase = iFrameNo * iFrameSize;
const SINT iFrameBase = iFrameNo * iFrameSize;
outputBuffer[iFrameBase + iChannelBase] = SampleUtil::clampSample(
(pAudioOutputBuffer[iFrameNo * 2] +
pAudioOutputBuffer[iFrameNo * 2 + 1]) / 2.0f);
}
} else {
for (unsigned int iFrameNo = 0; iFrameNo < framesToCompose; ++iFrameNo) {
for (SINT iFrameNo = 0; iFrameNo < framesToCompose; ++iFrameNo) {
// iFrameBase is the "base sample" in a frame (ie. the first
// sample in a frame)
const unsigned int iFrameBase = iFrameNo * iFrameSize;
const unsigned int iLocalFrameBase = iFrameNo * iChannelCount;
const SINT iFrameBase = iFrameNo * iFrameSize;
const SINT iLocalFrameBase = iFrameNo * iChannelCount;

// this will make sure a sample from each channel is copied
for (int iChannel = 0; iChannel < iChannelCount; ++iChannel) {
Expand All @@ -182,9 +182,9 @@ void SoundDevice::composeOutputBuffer(CSAMPLE* outputBuffer,
}

void SoundDevice::composeInputBuffer(const CSAMPLE* inputBuffer,
const unsigned int framesToPush,
const unsigned int framesWriteOffset,
const unsigned int iFrameSize) {
const SINT framesToPush,
const SINT framesWriteOffset,
const int iFrameSize) {
//qDebug() << "SoundManager::pushBuffer"
// << framesToPush << framesWriteOffset << iFrameSize;
// This function is called a *lot* and is a big source of CPU usage.
Expand All @@ -199,7 +199,7 @@ void SoundDevice::composeInputBuffer(const CSAMPLE* inputBuffer,
const AudioInputBuffer& in = m_audioInputs.at(0);
CSAMPLE* pInputBuffer = in.getBuffer(); // Always Stereo
pInputBuffer = &pInputBuffer[framesWriteOffset * 2];
for (unsigned int iFrameNo = 0; iFrameNo < framesToPush; ++iFrameNo) {
for (SINT iFrameNo = 0; iFrameNo < framesToPush; ++iFrameNo) {
pInputBuffer[iFrameNo * 2] =
inputBuffer[iFrameNo];
pInputBuffer[iFrameNo * 2 + 1] =
Expand All @@ -225,11 +225,11 @@ void SoundDevice::composeInputBuffer(const CSAMPLE* inputBuffer,
CSAMPLE* pInputBuffer = in.getBuffer();
pInputBuffer = &pInputBuffer[framesWriteOffset * 2];

for (unsigned int iFrameNo = 0; iFrameNo < framesToPush; ++iFrameNo) {
for (SINT iFrameNo = 0; iFrameNo < framesToPush; ++iFrameNo) {
// iFrameBase is the "base sample" in a frame (ie. the first
// sample in a frame)
unsigned int iFrameBase = iFrameNo * iFrameSize;
unsigned int iLocalFrameBase = iFrameNo * 2;
SINT iFrameBase = iFrameNo * iFrameSize;
SINT iLocalFrameBase = iFrameNo * 2;

if (iChannelCount == 1) {
pInputBuffer[iLocalFrameBase] =
Expand All @@ -247,9 +247,8 @@ void SoundDevice::composeInputBuffer(const CSAMPLE* inputBuffer,
}
}

void SoundDevice::clearInputBuffer(const unsigned int framesToPush,
const unsigned int framesWriteOffset) {

void SoundDevice::clearInputBuffer(const SINT framesToPush,
const SINT framesWriteOffset) {
for (QList<AudioInputBuffer>::const_iterator i = m_audioInputs.begin(),
e = m_audioInputs.end(); i != e; ++i) {
const AudioInputBuffer& in = *i;
Expand Down
18 changes: 9 additions & 9 deletions src/soundio/sounddevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,17 @@ class SoundDevice {

protected:
void composeOutputBuffer(CSAMPLE* outputBuffer,
const unsigned int iFramesPerBuffer,
const unsigned int readOffset,
const unsigned int iFrameSize);
const SINT iFramesPerBuffer,
const SINT readOffset,
const int iFrameSize);

void composeInputBuffer(const CSAMPLE* inputBuffer,
const unsigned int framesToPush,
const unsigned int framesWriteOffset,
const unsigned int iFrameSize);
const SINT framesToPush,
const SINT framesWriteOffset,
const int iFrameSize);

void clearInputBuffer(const unsigned int framesToPush,
const unsigned int framesWriteOffset);
void clearInputBuffer(const SINT framesToPush,
const SINT framesWriteOffset);

UserSettingsPointer m_pConfig;
// Pointer to the SoundManager object which we'll request audio from.
Expand All @@ -100,7 +100,7 @@ class SoundDevice {
double m_dSampleRate;
// The name of the audio API used by this device.
QString m_hostAPI;
unsigned int m_framesPerBuffer;
SINT m_framesPerBuffer;
QList<AudioOutputBuffer> m_audioOutputs;
QList<AudioInputBuffer> m_audioInputs;
};
Expand Down
Loading