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

fix #286900 MIDI input menu has no None option #4853

Closed
wants to merge 1 commit into from
Closed
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
69 changes: 43 additions & 26 deletions audio/drivers/pm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,18 @@ PortMidiDriver::PortMidiDriver(Seq* s)

PortMidiDriver::~PortMidiDriver()
{
if (timer) {
timer->stop();
delete timer;
}
if (inputStream) {
Pt_Stop();
Pm_Close(inputStream);
}
if (outputStream) {
Pt_Stop();
Pm_Close(outputStream);
}
}

//---------------------------------------------------------
Expand All @@ -64,41 +72,50 @@ PortMidiDriver::~PortMidiDriver()

bool PortMidiDriver::init()
{
inputId = getDeviceIn(preferences.getString(PREF_IO_PORTMIDI_INPUTDEVICE));
if (inputId == -1)
inputId = Pm_GetDefaultInputDeviceID();

if (inputId == pmNoDevice)
return false;

inputId = getDeviceIn(preferences.getString(PREF_IO_PORTMIDI_INPUTDEVICE)); // Note: allow init even if inputId == pmNoDevice, in case of output
outputId = getDeviceOut(preferences.getString(PREF_IO_PORTMIDI_OUTPUTDEVICE)); // Note: allow init even if outputId == pmNoDevice, since input is more important than output.

bool autoGrabbing = false;
if ((inputId == -1) && (preferences.getString(PREF_IO_PORTMIDI_INPUTDEVICE) != " ")) {
inputId = Pm_GetDefaultInputDeviceID();
autoGrabbing = true;
}
// do not automatically grab the same device as both input and output
if (autoGrabbing && (outputId != -1)) {
const PmDeviceInfo* info = Pm_GetDeviceInfo(inputId);
QString portmidiInputDevice;
if (info && (info->input))
portmidiInputDevice = QString(info->interf) + "," + QString(info->name);
if (portmidiInputDevice == preferences.getString(PREF_IO_PORTMIDI_OUTPUTDEVICE))
inputId = -1;
}
if ((inputId == pmNoDevice) && (outputId == pmNoDevice) && (preferences.getString(PREF_IO_PORTMIDI_INPUTDEVICE) != " "))
return false;
static const int DRIVER_INFO = 0;
static const int TIME_INFO = 0;

Pt_Start(20, 0, 0); // timer started, 20 millisecond accuracy

PmError error = Pm_OpenInput(&inputStream,
inputId,
(void*)DRIVER_INFO,
preferences.getInt(PREF_IO_PORTMIDI_INPUTBUFFERCOUNT),
((PmTimeProcPtr) Pt_Time),
(void*)TIME_INFO);
if (error != pmNoError) {
const char* p = Pm_GetErrorText(error);
qDebug("PortMidi: open input (id=%d) failed: %s", int(inputId), p);
Pt_Stop();
return false;
if (inputId != pmNoDevice) {
PmError error = Pm_OpenInput(&inputStream,
inputId,
(void*)DRIVER_INFO,
preferences.getInt(PREF_IO_PORTMIDI_INPUTBUFFERCOUNT),
((PmTimeProcPtr) Pt_Time),
(void*)TIME_INFO);
if (error != pmNoError) {
const char* p = Pm_GetErrorText(error);
qDebug("PortMidi: open input (id=%d) failed: %s", int(inputId), p);
Pt_Stop();
return false;
}
Pm_SetFilter(inputStream, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
PmEvent buffer[1];
while (Pm_Poll(inputStream))
Pm_Read(inputStream, buffer, 1);
}

Pm_SetFilter(inputStream, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);

PmEvent buffer[1];
while (Pm_Poll(inputStream))
Pm_Read(inputStream, buffer, 1);

if (outputId != pmNoDevice) {
error = Pm_OpenOutput(&outputStream,
PmError error = Pm_OpenOutput(&outputStream,
outputId,
(void*)DRIVER_INFO,
preferences.getInt(PREF_IO_PORTMIDI_OUTPUTBUFFERCOUNT),
Expand Down
1 change: 1 addition & 0 deletions audio/drivers/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class PortMidiDriver : public MidiDriver {
PmStream* getOutputStream() { return outputStream; }
bool canOutput() { return outputStream != 0; }
bool isSameCoreMidiIacBus(const QString& inInterfaceAndName, const QString& outInterfaceAndName);
int getInputId() { return inputId; }
};


Expand Down
14 changes: 11 additions & 3 deletions mscore/prefsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,10 +711,18 @@ void PreferenceDialog::updateValues(bool useDefaultValues, bool setup)
QStringList midiInputs = midiDriver->deviceInList();
int curMidiInIdx = 0;
portMidiInput->clear();
portMidiInput->insertItem(0," "); // note: a space to be different from the default empty string.
// The current input device can be different from the saved preference if the preference was empty
// because of automatic grabbing of the default input device if not explicitly told otherwise.
// Therefore, comparison must be done with respect to the actual current input device name.
const PmDeviceInfo* info = Pm_GetDeviceInfo(midiDriver->getInputId());
QString portmidiInputDevice;
if(info && (info->input))
portmidiInputDevice = QString(info->interf) + "," + QString(info->name);
for(int i = 0; i < midiInputs.size(); ++i) {
portMidiInput->addItem(midiInputs.at(i), i);
if (midiInputs.at(i) == preferences.getString(PREF_IO_PORTMIDI_INPUTDEVICE))
curMidiInIdx = i;
portMidiInput->insertItem(i+1, midiInputs.at(i));
if (midiInputs.at(i) == portmidiInputDevice)
curMidiInIdx = i + 1;
}
portMidiInput->setCurrentIndex(curMidiInIdx);

Expand Down