Skip to content

Commit

Permalink
Jack midi improvements
Browse files Browse the repository at this point in the history
-dependency jackaudio & jackmidi (caused crash on exit)
+jack midi out
  • Loading branch information
justnope committed May 30, 2018
1 parent 9af5ac8 commit abb13bd
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 70 deletions.
8 changes: 0 additions & 8 deletions include/AudioJack.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ class AudioJack : public QObject, public AudioDevice
AudioJack( bool & _success_ful, Mixer* mixer );
virtual ~AudioJack();

// 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);
jack_client_t * jackClient() {return m_client;};

inline static QString name()
{
return QT_TRANSLATE_NOOP( "setupWidget",
Expand All @@ -78,7 +72,6 @@ class AudioJack : public QObject, public AudioDevice
private:
QLineEdit * m_clientName;
LcdSpinBox * m_channels;

} ;


Expand Down Expand Up @@ -110,7 +103,6 @@ private slots:
bool m_stopped;
QMutex m_processingMutex;

MidiJack *m_midiClient;
QVector<jack_port_t *> m_outputPorts;
jack_default_audio_sample_t * * m_tempOutBufs;
surroundSampleFrame * m_outBuf;
Expand Down
20 changes: 9 additions & 11 deletions include/MidiJack.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@
#include <QtCore/QThread>
#include <QMutex>
#include <QtCore/QFile>

#include <mutex>
#include <vector>
#include "MidiClient.h"
#include "AudioJack.h"


#define JACK_MIDI_BUFFER_MAX 64 /* events */

class QLineEdit;
Expand All @@ -52,7 +54,7 @@ class MidiJack : public QThread, public MidiClientRaw
public:
MidiJack();
virtual ~MidiJack();

jack_client_t* jackClient();

static QString probeDevice();
Expand All @@ -79,20 +81,16 @@ class MidiJack : public QThread, public MidiClientRaw


private:
AudioJack *m_jackAudio;
//TODO: (experimental) replace this with a more efficient way
//also don't use sendByte but processOutEvent to get timings
std::mutex m_bufferLock;
std::vector<unsigned char> m_midibuffer;

jack_client_t *m_jackClient;
jack_port_t *m_input_port;
jack_port_t *m_output_port;
uint8_t m_jack_buffer[JACK_MIDI_BUFFER_MAX * 4];

void JackMidiOutEvent(uint8_t *buf, uint8_t len);
void lock();
void unlock();

void getPortInfo( const QString& sPortName, int& nClient, int& nPort );

volatile bool m_quit;

};

#endif // LMMS_HAVE_JACK
Expand Down
2 changes: 1 addition & 1 deletion src/core/Mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ Mixer::~Mixer()
}
delete m_fifo;

delete m_audioDev;
delete m_midiClient;
delete m_audioDev;

for( int i = 0; i < 3; i++ )
{
Expand Down
21 changes: 2 additions & 19 deletions src/core/audio/AudioJack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ AudioJack::AudioJack( bool & _success_ful, Mixer* _mixer ) :
_mixer ),
m_client( NULL ),
m_active( false ),
m_midiClient( NULL ),
m_tempOutBufs( new jack_default_audio_sample_t *[channels()] ),
m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ),
m_framesDoneInCurBuf( 0 ),
Expand Down Expand Up @@ -79,13 +78,14 @@ AudioJack::~AudioJack()
}
#endif

if( m_client != NULL )
if( m_client != nullptr )
{
if( m_active )
{
jack_deactivate( m_client );
}
jack_client_close( m_client );
m_client = nullptr;
}

delete[] m_tempOutBufs;
Expand Down Expand Up @@ -123,15 +123,6 @@ void AudioJack::restartAfterZombified()



AudioJack* AudioJack::addMidiClient(MidiJack *midiClient)
{
if( m_client == NULL )
return NULL;

m_midiClient = midiClient;

return this;
}

bool AudioJack::initJackClient()
{
Expand Down Expand Up @@ -346,14 +337,6 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata )
{
QMutexLocker m( &m_processingMutex );

// do midi processing first so that midi input can
// add to the following sound processing
if( m_midiClient && _nframes > 0 )
{
m_midiClient->JackMidiRead(_nframes);
m_midiClient->JackMidiWrite(_nframes);
}

for( int c = 0; c < channels(); ++c )
{
m_tempOutBufs[c] =
Expand Down
58 changes: 27 additions & 31 deletions src/core/midi/MidiJack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,39 +65,26 @@ MidiJack::MidiJack() :
m_output_port( NULL ),
m_quit( false )
{
// if jack is currently used for audio then we share the connection
// AudioJack creates and maintains the jack connection
// and also handles the callback, we pass it our address
// so that we can also process during the callback
m_jackClient = jack_client_open(probeDevice().toLatin1().data(),
JackNoStartServer, NULL);

m_jackAudio = dynamic_cast<AudioJack*>(Engine::mixer()->audioDev());
if( m_jackAudio )
if(m_jackClient)
{
// if a jack connection has been created for audio we use that
m_jackAudio->addMidiClient(this);
}else{
m_jackAudio = NULL;
m_jackClient = jack_client_open(probeDevice().toLatin1().data(),
JackNoStartServer, NULL);

if(m_jackClient)
{
jack_set_process_callback(m_jackClient,
JackMidiProcessCallback, this);
jack_on_shutdown(m_jackClient,
JackMidiShutdown, 0);
}
jack_set_process_callback(m_jackClient,
JackMidiProcessCallback, this);
jack_on_shutdown(m_jackClient,
JackMidiShutdown, 0);
}

if(jackClient())
{
/* jack midi out not implemented
JackMidiWrite and sendByte needs to be functional
before enabling this
before enabling this*/
m_output_port = jack_port_register(
jackClient(), "MIDI out", JACK_DEFAULT_MIDI_TYPE,
JackPortIsOutput, 0);
*/


m_input_port = jack_port_register(
jackClient(), "MIDI in", JACK_DEFAULT_MIDI_TYPE,
Expand Down Expand Up @@ -145,13 +132,7 @@ MidiJack::~MidiJack()

jack_client_t* MidiJack::jackClient()
{
if( m_jackAudio == NULL && m_jackClient == NULL)
return NULL;

if( m_jackAudio == NULL && m_jackClient )
return m_jackClient;

return m_jackAudio->jackClient();
return m_jackClient;
}

QString MidiJack::probeDevice()
Expand Down Expand Up @@ -197,13 +178,28 @@ void MidiJack::JackMidiRead(jack_nframes_t nframes)

void MidiJack::sendByte( const unsigned char c )
{
//m_midiDev.putChar( c );
std::lock_guard<std::mutex> lock(m_bufferLock);
m_midibuffer.push_back(c);
}

// we write data to jack
void MidiJack::JackMidiWrite(jack_nframes_t nframes)
{
// TODO: write midi data to jack port
{
std::lock_guard<std::mutex> lock(m_bufferLock);
if (!m_midibuffer.empty())
{
void* portBuffer = jack_port_get_buffer(m_output_port, nframes);
jack_midi_clear_buffer(portBuffer);
void* buffer = jack_midi_event_reserve(portBuffer, 0, m_midibuffer.size());
if (buffer)
{
memcpy(buffer, m_midibuffer.data(), m_midibuffer.size());
}
m_midibuffer.clear();
}
}

}

void MidiJack::run()
Expand Down

0 comments on commit abb13bd

Please sign in to comment.