Basic JACK MIDI In support
This commit is contained in:
parent
e5812556a7
commit
122887f471
5 changed files with 49 additions and 13 deletions
|
@ -25,6 +25,7 @@ namespace Ms {
|
|||
|
||||
class Seq;
|
||||
class Event;
|
||||
class NPlayEvent;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Driver
|
||||
|
@ -48,7 +49,7 @@ class Driver {
|
|||
virtual int sampleRate() const = 0;
|
||||
virtual void registerPort(const QString& /*name*/, bool /*input*/, bool /*midi*/) {}
|
||||
virtual void unregisterPort(int) {}
|
||||
virtual void putEvent(const Event&, unsigned /*framePos*/) {}
|
||||
virtual void putEvent(const NPlayEvent&, unsigned /*framePos*/) {}
|
||||
virtual void midiRead() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ JackAudio::JackAudio(Seq* s)
|
|||
JackAudio::~JackAudio()
|
||||
{
|
||||
if (client) {
|
||||
stop();
|
||||
if (jack_client_close(client)) {
|
||||
qDebug("jack_client_close() failed: %s",
|
||||
strerror(errno));
|
||||
|
@ -226,7 +227,7 @@ bool JackAudio::stop()
|
|||
{
|
||||
if (preferences.useJackMidi && preferences.rememberLastMidiConnections) {
|
||||
QSettings settings;
|
||||
settings.setValue("midiPorts", midiOutputPorts.size());
|
||||
//settings.setValue("midiPorts", midiOutputPorts.size());
|
||||
int port = 0;
|
||||
foreach(jack_port_t* mp, midiOutputPorts) {
|
||||
const char** cc = jack_port_get_connections(mp);
|
||||
|
@ -243,7 +244,8 @@ bool JackAudio::stop()
|
|||
free((void*)cc);
|
||||
++port;
|
||||
}
|
||||
settings.setValue("midiInputPorts", midiInputPorts.size());
|
||||
// We don't use it now
|
||||
//settings.setValue("midiInputPorts", midiInputPorts.size());
|
||||
port = 0;
|
||||
foreach(jack_port_t* mp, midiInputPorts) {
|
||||
const char** cc = jack_port_get_connections(mp);
|
||||
|
@ -374,6 +376,11 @@ int JackAudio::processAudio(jack_nframes_t frames, void* p)
|
|||
*r++ = *sp++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// JACK MIDI only
|
||||
float buffer[frames * 2];
|
||||
audio->seq->process((unsigned)frames, buffer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -390,8 +397,9 @@ static void jackError(const char *s)
|
|||
// noJackError
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void noJackError(const char* /* s */)
|
||||
static void noJackError(const char* s )
|
||||
{
|
||||
qDebug("noJACK ERROR: %s", s);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -504,7 +512,7 @@ int JackAudio::getState()
|
|||
// putEvent
|
||||
//---------------------------------------------------------
|
||||
|
||||
void JackAudio::putEvent(const Event& e, unsigned framePos)
|
||||
void JackAudio::putEvent(const NPlayEvent& e, unsigned framePos)
|
||||
{
|
||||
if (!preferences.useJackMidi)
|
||||
return;
|
||||
|
@ -562,7 +570,8 @@ void JackAudio::putEvent(const Event& e, unsigned framePos)
|
|||
p[1] = e.dataA();
|
||||
}
|
||||
break;
|
||||
case ME_SYSEX:
|
||||
// Do we really need to handle ME_SYSEX?
|
||||
/* case ME_SYSEX:
|
||||
{
|
||||
const unsigned char* data = e.edata();
|
||||
int len = e.len();
|
||||
|
@ -575,7 +584,7 @@ void JackAudio::putEvent(const Event& e, unsigned framePos)
|
|||
p[len+1] = 0xf7;
|
||||
memcpy(p+1, data, len);
|
||||
}
|
||||
break;
|
||||
break;*/
|
||||
case ME_SONGPOS:
|
||||
case ME_CLOCK:
|
||||
case ME_START:
|
||||
|
|
|
@ -62,7 +62,7 @@ class JackAudio : public Driver {
|
|||
virtual void stopTransport();
|
||||
virtual int getState();
|
||||
virtual int sampleRate() const { return jack_get_sample_rate(client); }
|
||||
virtual void putEvent(const Event&, unsigned framePos);
|
||||
virtual void putEvent(const NPlayEvent&, unsigned framePos);
|
||||
virtual void midiRead();
|
||||
|
||||
virtual void registerPort(const QString& name, bool input, bool midi);
|
||||
|
|
|
@ -827,6 +827,7 @@ void PreferenceDialog::updateValues()
|
|||
portaudioDriver->setChecked(prefs.usePortaudioAudio);
|
||||
pulseaudioDriver->setChecked(prefs.usePulseAudio);
|
||||
useJackMidi->setChecked(prefs.useJackMidi);
|
||||
useSynthesizer->setChecked(prefs.useAlsaAudio || prefs.useJackAudio || prefs.usePortaudioAudio || prefs.usePulseAudio);
|
||||
|
||||
alsaDevice->setText(prefs.alsaDevice);
|
||||
|
||||
|
|
|
@ -650,20 +650,43 @@ void Seq::process(unsigned n, float* buffer)
|
|||
int driverState = _driver->getState();
|
||||
|
||||
if (driverState != state) {
|
||||
// Got a message from JACK Transport panel: Play
|
||||
if (state == TRANSPORT_STOP && driverState == TRANSPORT_PLAY) {
|
||||
|
||||
if((preferences.useJackMidi || preferences.useJackAudio) && !getAction("play")->isChecked()) {
|
||||
// Do not play while editing elements
|
||||
if(mscore->state()==STATE_NORMAL && isRunning() && canStart()) {
|
||||
if (playlistChanged)
|
||||
collectEvents();
|
||||
getAction("play")->setChecked(true);
|
||||
getAction("play")->triggered(true);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Need to change state after calling collectEvents()
|
||||
state = TRANSPORT_PLAY;
|
||||
if (mscore->countIn() && cs->playMode() == PlayMode::SYNTHESIZER) {
|
||||
if (mscore->countIn() && cs->playMode() == PLAYMODE_SYNTHESIZER) {
|
||||
countInEvents.clear();
|
||||
inCountIn = true;
|
||||
}
|
||||
emit toGui('1');
|
||||
}
|
||||
// Got a message from JACK Transport panel: Stop
|
||||
else if (state == TRANSPORT_PLAY && driverState == TRANSPORT_STOP) {
|
||||
state = TRANSPORT_STOP;
|
||||
stopNotes();
|
||||
// send sustain off
|
||||
// TODO: channel?
|
||||
putEvent(NPlayEvent(ME_CONTROLLER, 0, CTRL_SUSTAIN, 0));
|
||||
// Muting all notes
|
||||
if(preferences.useAlsaAudio || preferences.useJackAudio || preferences.usePulseAudio || preferences.usePortaudioAudio || preferences.useOsc)
|
||||
stopNotes();
|
||||
if(preferences.useJackMidi)
|
||||
for(int ch=0; ch<cs->midiMapping()->size();ch++) {
|
||||
// send sustain off
|
||||
putEvent(NPlayEvent(ME_CONTROLLER, ch, CTRL_SUSTAIN, 0));
|
||||
for(int i=0; i<128; i++)
|
||||
putEvent(NPlayEvent(ME_NOTEOFF,ch,i,0));
|
||||
}
|
||||
|
||||
if (playPos == events.cend()) {
|
||||
if (mscore->loop()) {
|
||||
qDebug("Seq.cpp - Process - Loop whole score. playPos = %d cs->pos() = %d", playPos->first,cs->pos());
|
||||
|
@ -1237,6 +1260,8 @@ void Seq::putEvent(const NPlayEvent& event)
|
|||
}
|
||||
int syntiIdx= _synti->index(cs->midiMapping(channel)->articulation->synti);
|
||||
_synti->play(event, syntiIdx);
|
||||
if (preferences.useJackMidi)
|
||||
driver()->putEvent(event,0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue