diff --git a/include/AudioJack.h b/include/AudioJack.h index 164258e5f..6efb262ed 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -57,42 +57,37 @@ class AudioJack : public QObject, public AudioDevice { Q_OBJECT public: - AudioJack( bool & _success_ful, AudioEngine* audioEngine ); + AudioJack(bool& successful, AudioEngine* audioEngine); ~AudioJack() override; // this is to allow the jack midi connection to use the same jack client connection // the jack callback is handled here, we call the midi client so that it can read // it's midi data during the callback - AudioJack * addMidiClient(MidiJack *midiClient); + AudioJack* addMidiClient(MidiJack* midiClient); void removeMidiClient() { m_midiClient = nullptr; } - jack_client_t * jackClient() {return m_client;}; + jack_client_t* jackClient() { return m_client; }; inline static QString name() { - return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget", - "JACK (JACK Audio Connection Kit)" ); + return QT_TRANSLATE_NOOP("AudioDeviceSetupWidget", "JACK (JACK Audio Connection Kit)"); } - -class setupWidget : public gui::AudioDeviceSetupWidget + class setupWidget : public gui::AudioDeviceSetupWidget { public: - setupWidget( QWidget * _parent ); + setupWidget(QWidget* parent); ~setupWidget() override; void saveSettings() override; private: - QLineEdit * m_clientName; - gui::LcdSpinBox * m_channels; - - } ; - + QLineEdit* m_clientName; + gui::LcdSpinBox* m_channels; + }; private slots: void restartAfterZombified(); - private: bool initJackClient(); @@ -100,45 +95,41 @@ private: void stopProcessing() override; void applyQualitySettings() override; - void registerPort( AudioPort * _port ) override; - void unregisterPort( AudioPort * _port ) override; - void renamePort( AudioPort * _port ) override; + void registerPort(AudioPort* port) override; + void unregisterPort(AudioPort* port) override; + void renamePort(AudioPort* port) override; - int processCallback( jack_nframes_t _nframes, void * _udata ); + int processCallback(jack_nframes_t nframes); - static int staticProcessCallback( jack_nframes_t _nframes, - void * _udata ); - static void shutdownCallback( void * _udata ); + static int staticProcessCallback(jack_nframes_t nframes, void* udata); + static void shutdownCallback(void* _udata); - - jack_client_t * m_client; + jack_client_t* m_client; bool m_active; std::atomic m_stopped; - std::atomic m_midiClient; - std::vector m_outputPorts; - jack_default_audio_sample_t * * m_tempOutBufs; - surroundSampleFrame * m_outBuf; + std::atomic m_midiClient; + std::vector m_outputPorts; + jack_default_audio_sample_t** m_tempOutBufs; + surroundSampleFrame* m_outBuf; f_cnt_t m_framesDoneInCurBuf; f_cnt_t m_framesToDoInCurBuf; - #ifdef AUDIO_PORT_SUPPORT struct StereoPort { - jack_port_t * ports[2]; - } ; + jack_port_t* ports[2]; + }; - using JackPortMap = QMap; + using JackPortMap = QMap; JackPortMap m_portMap; #endif signals: void zombified(); - -} ; +}; } // namespace lmms diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index dc6bc2861..55382f715 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -30,42 +30,43 @@ #include #include +#include "AudioEngine.h" +#include "ConfigManager.h" #include "Engine.h" #include "GuiApplication.h" -#include "gui_templates.h" -#include "ConfigManager.h" #include "LcdSpinBox.h" #include "MainWindow.h" -#include "AudioEngine.h" #include "MidiJack.h" - +#include "gui_templates.h" namespace lmms { -AudioJack::AudioJack( bool & _success_ful, AudioEngine* _audioEngine ) : - AudioDevice(std::clamp( - ConfigManager::inst()->value("audiojack", "channels").toInt(), - DEFAULT_CHANNELS, - SURROUND_CHANNELS), _audioEngine), - m_client( nullptr ), - m_active( false ), - m_midiClient( nullptr ), - m_tempOutBufs( new jack_default_audio_sample_t *[channels()] ), - m_outBuf( new surroundSampleFrame[audioEngine()->framesPerPeriod()] ), - m_framesDoneInCurBuf( 0 ), - m_framesToDoInCurBuf( 0 ) + +AudioJack::AudioJack(bool& successful, AudioEngine* audioEngineParam) + : AudioDevice( + // clang-format off + std::clamp( + ConfigManager::inst()->value("audiojack", "channels").toInt(), + DEFAULT_CHANNELS, + SURROUND_CHANNELS + ), + // clang-format on + audioEngineParam) + , m_client(nullptr) + , m_active(false) + , m_midiClient(nullptr) + , m_tempOutBufs(new jack_default_audio_sample_t*[channels()]) + , m_outBuf(new surroundSampleFrame[audioEngine()->framesPerPeriod()]) + , m_framesDoneInCurBuf(0) + , m_framesToDoInCurBuf(0) { m_stopped = true; - _success_ful = initJackClient(); - if( _success_ful ) - { - connect( this, SIGNAL(zombified()), - this, SLOT(restartAfterZombified()), - Qt::QueuedConnection ); + successful = initJackClient(); + if (successful) { + connect(this, SIGNAL(zombified()), this, SLOT(restartAfterZombified()), Qt::QueuedConnection); } - } @@ -73,21 +74,18 @@ AudioJack::AudioJack( bool & _success_ful, AudioEngine* _audioEngine ) : AudioJack::~AudioJack() { - stopProcessing(); + AudioJack::stopProcessing(); #ifdef AUDIO_PORT_SUPPORT - while( m_portMap.size() ) + while (m_portMap.size()) { - unregisterPort( m_portMap.begin().key() ); + unregisterPort(m_portMap.begin().key()); } #endif - if( m_client != nullptr ) + if (m_client != nullptr) { - if( m_active ) - { - jack_deactivate( m_client ); - } - jack_client_close( m_client ); + if (m_active) { jack_deactivate(m_client); } + jack_client_close(m_client); } delete[] m_tempOutBufs; @@ -100,97 +98,79 @@ AudioJack::~AudioJack() void AudioJack::restartAfterZombified() { - if( initJackClient() ) + if (initJackClient()) { m_active = false; startProcessing(); - QMessageBox::information(gui::getGUI()->mainWindow(), - tr( "JACK client restarted" ), - tr( "LMMS was kicked by JACK for some reason. " + QMessageBox::information(gui::getGUI()->mainWindow(), tr("JACK client restarted"), + tr( "LMMS was kicked by JACK for some reason. " "Therefore the JACK backend of LMMS has been " "restarted. You will have to make manual " - "connections again." ) ); + "connections again.")); } else { - QMessageBox::information(gui::getGUI()->mainWindow(), - tr( "JACK server down" ), - tr( "The JACK server seems to have been shutdown " + QMessageBox::information(gui::getGUI()->mainWindow(), tr("JACK server down"), + tr( "The JACK server seems to have been shutdown " "and starting a new instance failed. " "Therefore LMMS is unable to proceed. " "You should save your project and restart " - "JACK and LMMS." ) ); + "JACK and LMMS.")); } } -AudioJack* AudioJack::addMidiClient(MidiJack *midiClient) + +AudioJack* AudioJack::addMidiClient(MidiJack* midiClient) { - if( m_client == nullptr ) - return nullptr; + if (m_client == nullptr) { return nullptr; } m_midiClient = midiClient; return this; } + + + bool AudioJack::initJackClient() { - QString clientName = ConfigManager::inst()->value( "audiojack", - "clientname" ); - if( clientName.isEmpty() ) - { - clientName = "lmms"; - } + QString clientName = ConfigManager::inst()->value("audiojack", "clientname"); + if (clientName.isEmpty()) { clientName = "lmms"; } - const char * serverName = nullptr; + const char* serverName = nullptr; jack_status_t status; - m_client = jack_client_open( clientName.toLatin1().constData(), - JackNullOption, &status, - serverName ); - if( m_client == nullptr ) + m_client = jack_client_open(clientName.toLatin1().constData(), JackNullOption, &status, serverName); + if (m_client == nullptr) { - printf( "jack_client_open() failed, status 0x%2.0x\n", status ); - if( status & JackServerFailed ) - { - printf( "Could not connect to JACK server.\n" ); - } + printf("jack_client_open() failed, status 0x%2.0x\n", status); + if (status & JackServerFailed) { printf("Could not connect to JACK server.\n"); } return false; } - if( status & JackNameNotUnique ) + if (status & JackNameNotUnique) { - printf( "there's already a client with name '%s', so unique " - "name '%s' was assigned\n", clientName. - toLatin1().constData(), - jack_get_client_name( m_client ) ); + printf( "there's already a client with name '%s', so unique " + "name '%s' was assigned\n", + clientName.toLatin1().constData(), jack_get_client_name(m_client)); } // set process-callback - jack_set_process_callback( m_client, staticProcessCallback, this ); + jack_set_process_callback(m_client, staticProcessCallback, this); // set shutdown-callback - jack_on_shutdown( m_client, shutdownCallback, this ); + jack_on_shutdown(m_client, shutdownCallback, this); + if (jack_get_sample_rate(m_client) != sampleRate()) { setSampleRate(jack_get_sample_rate(m_client)); } - - if( jack_get_sample_rate( m_client ) != sampleRate() ) + for (ch_cnt_t ch = 0; ch < channels(); ++ch) { - setSampleRate( jack_get_sample_rate( m_client ) ); - } - - for( ch_cnt_t ch = 0; ch < channels(); ++ch ) - { - QString name = QString( "master out " ) + - ( ( ch % 2 ) ? "R" : "L" ) + - QString::number( ch / 2 + 1 ); - m_outputPorts.push_back( jack_port_register( m_client, - name.toLatin1().constData(), - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0 ) ); - if( m_outputPorts.back() == nullptr ) + QString name = QString("master out ") + ((ch % 2) ? "R" : "L") + QString::number(ch / 2 + 1); + m_outputPorts.push_back( + jack_port_register(m_client, name.toLatin1().constData(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)); + if (m_outputPorts.back() == nullptr) { - printf( "no more JACK-ports available!\n" ); + printf("no more JACK-ports available!\n"); return false; } } @@ -203,51 +183,43 @@ bool AudioJack::initJackClient() void AudioJack::startProcessing() { - if( m_active || m_client == nullptr ) + if (m_active || m_client == nullptr) { m_stopped = false; return; } - if( jack_activate( m_client ) ) + if (jack_activate(m_client)) { - printf( "cannot activate client\n" ); + printf("cannot activate client\n"); return; } m_active = true; - // try to sync JACK's and LMMS's buffer-size -// jack_set_buffer_size( m_client, audioEngine()->framesPerPeriod() ); + // jack_set_buffer_size( m_client, audioEngine()->framesPerPeriod() ); - - - const char * * ports = jack_get_ports( m_client, nullptr, nullptr, - JackPortIsPhysical | - JackPortIsInput ); - if( ports == nullptr ) + const char** ports = jack_get_ports(m_client, nullptr, nullptr, JackPortIsPhysical | JackPortIsInput); + if (ports == nullptr) { - printf( "no physical playback ports. you'll have to do " - "connections at your own!\n" ); + printf("no physical playback ports. you'll have to do " + "connections at your own!\n"); } else { - for( ch_cnt_t ch = 0; ch < channels(); ++ch ) + for (ch_cnt_t ch = 0; ch < channels(); ++ch) { - if( jack_connect( m_client, jack_port_name( - m_outputPorts[ch] ), - ports[ch] ) ) + if (jack_connect(m_client, jack_port_name(m_outputPorts[ch]), ports[ch])) { - printf( "cannot connect output ports. you'll " - "have to do connections at your own!\n" - ); + printf("cannot connect output ports. you'll " + "have to do connections at your own!\n"); } } } m_stopped = false; - free( ports ); + free(ports); } @@ -263,14 +235,11 @@ void AudioJack::stopProcessing() void AudioJack::applyQualitySettings() { - if( hqAudio() ) + if (hqAudio()) { - setSampleRate( Engine::audioEngine()->processingSampleRate() ); + setSampleRate(Engine::audioEngine()->processingSampleRate()); - if( jack_get_sample_rate( m_client ) != sampleRate() ) - { - setSampleRate( jack_get_sample_rate( m_client ) ); - } + if (jack_get_sample_rate(m_client) != sampleRate()) { setSampleRate(jack_get_sample_rate(m_client)); } } AudioDevice::applyQualitySettings(); @@ -279,106 +248,91 @@ void AudioJack::applyQualitySettings() -void AudioJack::registerPort( AudioPort * _port ) +void AudioJack::registerPort(AudioPort* port) { #ifdef AUDIO_PORT_SUPPORT // make sure, port is not already registered - unregisterPort( _port ); - const QString name[2] = { _port->name() + " L", - _port->name() + " R" } ; + unregisterPort(port); + const QString name[2] = {port->name() + " L", port->name() + " R"}; - for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) + for (ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch) { - m_portMap[_port].ports[ch] = jack_port_register( m_client, - name[ch].toLatin1().constData(), - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0 ); + m_portMap[port].ports[ch] = jack_port_register( + m_client, name[ch].toLatin1().constData(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); } +#else + (void)port; #endif } -void AudioJack::unregisterPort( AudioPort * _port ) +void AudioJack::unregisterPort(AudioPort* port) { #ifdef AUDIO_PORT_SUPPORT - if( m_portMap.contains( _port ) ) + if (m_portMap.contains(port)) { - for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) + for (ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch) { - if( m_portMap[_port].ports[ch] != nullptr ) - { - jack_port_unregister( m_client, - m_portMap[_port].ports[ch] ); - } + if (m_portMap[port].ports[ch] != nullptr) { jack_port_unregister(m_client, m_portMap[port].ports[ch]); } } - m_portMap.erase( m_portMap.find( _port ) ); + m_portMap.erase(m_portMap.find(port)); } +#else + (void)port; #endif } - - - -void AudioJack::renamePort( AudioPort * _port ) +void AudioJack::renamePort(AudioPort* port) { #ifdef AUDIO_PORT_SUPPORT - if( m_portMap.contains( _port ) ) + if (m_portMap.contains(port)) { - const QString name[2] = { _port->name() + " L", - _port->name() + " R" }; - for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) + const QString name[2] = {port->name() + " L", port->name() + " R"}; + for (ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch) { #ifdef LMMS_HAVE_JACK_PRENAME - jack_port_rename( m_client, m_portMap[_port].ports[ch], - name[ch].toLatin1().constData() ); + jack_port_rename(m_client, m_portMap[port].ports[ch], name[ch].toLatin1().constData()); #else - jack_port_set_name( m_portMap[_port].ports[ch], - name[ch].toLatin1().constData() ); + jack_port_set_name(m_portMap[port].ports[ch], name[ch].toLatin1().constData()); #endif } } +#else + (void)port; #endif // AUDIO_PORT_SUPPORT } -int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) +int AudioJack::processCallback(jack_nframes_t nframes) { // do midi processing first so that midi input can // add to the following sound processing - if( m_midiClient && _nframes > 0 ) + if (m_midiClient && nframes > 0) { - m_midiClient.load()->JackMidiRead(_nframes); - m_midiClient.load()->JackMidiWrite(_nframes); + m_midiClient.load()->JackMidiRead(nframes); + m_midiClient.load()->JackMidiWrite(nframes); } - for( int c = 0; c < channels(); ++c ) + for (int c = 0; c < channels(); ++c) { - m_tempOutBufs[c] = - (jack_default_audio_sample_t *) jack_port_get_buffer( - m_outputPorts[c], _nframes ); + m_tempOutBufs[c] = (jack_default_audio_sample_t*)jack_port_get_buffer(m_outputPorts[c], nframes); } #ifdef AUDIO_PORT_SUPPORT - const int frames = std::min(_nframes, audioEngine()->framesPerPeriod()); - for( JackPortMap::iterator it = m_portMap.begin(); - it != m_portMap.end(); ++it ) + const int frames = std::min(nframes, audioEngine()->framesPerPeriod()); + for (JackPortMap::iterator it = m_portMap.begin(); it != m_portMap.end(); ++it) { - for( ch_cnt_t ch = 0; ch < channels(); ++ch ) + for (ch_cnt_t ch = 0; ch < channels(); ++ch) { - if( it.value().ports[ch] == nullptr ) - { - continue; - } - jack_default_audio_sample_t * buf = - (jack_default_audio_sample_t *) jack_port_get_buffer( - it.value().ports[ch], - _nframes ); - for( int frame = 0; frame < frames; ++frame ) + if (it.value().ports[ch] == nullptr) { continue; } + jack_default_audio_sample_t* buf + = (jack_default_audio_sample_t*)jack_port_get_buffer(it.value().ports[ch], nframes); + for (int frame = 0; frame < frames; ++frame) { buf[frame] = it.key()->buffer()[frame][ch]; } @@ -387,28 +341,25 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) #endif jack_nframes_t done = 0; - while( done < _nframes && m_stopped == false ) + while (done < nframes && !m_stopped) { - jack_nframes_t todo = std::min( - _nframes-done, - m_framesToDoInCurBuf - - m_framesDoneInCurBuf); + jack_nframes_t todo = std::min(nframes - done, m_framesToDoInCurBuf - m_framesDoneInCurBuf); const float gain = audioEngine()->masterGain(); - for( int c = 0; c < channels(); ++c ) + for (int c = 0; c < channels(); ++c) { - jack_default_audio_sample_t * o = m_tempOutBufs[c]; - for( jack_nframes_t frame = 0; frame < todo; ++frame ) + jack_default_audio_sample_t* o = m_tempOutBufs[c]; + for (jack_nframes_t frame = 0; frame < todo; ++frame) { - o[done+frame] = m_outBuf[m_framesDoneInCurBuf+frame][c] * gain; + o[done + frame] = m_outBuf[m_framesDoneInCurBuf + frame][c] * gain; } } done += todo; m_framesDoneInCurBuf += todo; - if( m_framesDoneInCurBuf == m_framesToDoInCurBuf ) + if (m_framesDoneInCurBuf == m_framesToDoInCurBuf) { - m_framesToDoInCurBuf = getNextBuffer( m_outBuf ); + m_framesToDoInCurBuf = getNextBuffer(m_outBuf); m_framesDoneInCurBuf = 0; - if( !m_framesToDoInCurBuf ) + if (!m_framesToDoInCurBuf) { m_stopped = true; break; @@ -416,12 +367,12 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) } } - if( _nframes != done ) + if (nframes != done) { - for( int c = 0; c < channels(); ++c ) + for (int c = 0; c < channels(); ++c) { - jack_default_audio_sample_t * b = m_tempOutBufs[c] + done; - memset( b, 0, sizeof( *b ) * ( _nframes - done ) ); + jack_default_audio_sample_t* b = m_tempOutBufs[c] + done; + memset(b, 0, sizeof(*b) * (nframes - done)); } } @@ -431,51 +382,44 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) -int AudioJack::staticProcessCallback( jack_nframes_t _nframes, void * _udata ) +int AudioJack::staticProcessCallback(jack_nframes_t nframes, void* udata) { - return static_cast( _udata )-> - processCallback( _nframes, _udata ); + return static_cast(udata)->processCallback(nframes); } -void AudioJack::shutdownCallback( void * _udata ) +void AudioJack::shutdownCallback(void* udata) { - auto _this = static_cast(_udata); - _this->m_client = nullptr; - _this->zombified(); + auto thisClass = static_cast(udata); + thisClass->m_client = nullptr; + emit thisClass->zombified(); } - -AudioJack::setupWidget::setupWidget( QWidget * _parent ) : - AudioDeviceSetupWidget( AudioJack::name(), _parent ) +AudioJack::setupWidget::setupWidget(QWidget* parent) + : AudioDeviceSetupWidget(AudioJack::name(), parent) { QFormLayout * form = new QFormLayout(this); - QString cn = ConfigManager::inst()->value( "audiojack", "clientname" ); - if( cn.isEmpty() ) - { - cn = "lmms"; - } - m_clientName = new QLineEdit( cn, this ); + QString cn = ConfigManager::inst()->value("audiojack", "clientname"); + if (cn.isEmpty()) { cn = "lmms"; } + m_clientName = new QLineEdit(cn, this); form->addRow(tr("Client name"), m_clientName); auto m = new gui::LcdSpinBoxModel(/* this */); - m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); - m->setStep( 2 ); - m->setValue( ConfigManager::inst()->value( "audiojack", - "channels" ).toInt() ); + m->setRange(DEFAULT_CHANNELS, SURROUND_CHANNELS); + m->setStep(2); + m->setValue(ConfigManager::inst()->value("audiojack", "channels").toInt()); - m_channels = new gui::LcdSpinBox( 1, this ); - m_channels->setModel( m ); + m_channels = new gui::LcdSpinBox(1, this); + m_channels->setModel(m); form->addRow(tr("Channels"), m_channels); - } @@ -491,14 +435,11 @@ AudioJack::setupWidget::~setupWidget() void AudioJack::setupWidget::saveSettings() { - ConfigManager::inst()->setValue( "audiojack", "clientname", - m_clientName->text() ); - ConfigManager::inst()->setValue( "audiojack", "channels", - QString::number( m_channels->value() ) ); + ConfigManager::inst()->setValue("audiojack", "clientname", m_clientName->text()); + ConfigManager::inst()->setValue("audiojack", "channels", QString::number(m_channels->value())); } - } // namespace lmms #endif // LMMS_HAVE_JACK