mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-02 17:09:26 +02:00
PlayAtSpeed works for MIDI. Removed prefs for selecting MIDI input device (unless EXPERIMENTAL_MIDI_IN is on -- but there is no MIDI recording implemented at all)
This commit is contained in:
parent
28aaa34889
commit
08b98dce53
@ -515,6 +515,7 @@ AudioIO::AudioIO()
|
|||||||
mMidiStreamActive = false;
|
mMidiStreamActive = false;
|
||||||
mSendMidiState = false;
|
mSendMidiState = false;
|
||||||
mIterator = NULL;
|
mIterator = NULL;
|
||||||
|
mMidiPlaySpeed = 1.0;
|
||||||
|
|
||||||
mNumFrames = 0;
|
mNumFrames = 0;
|
||||||
mNumPauseFrames = 0;
|
mNumPauseFrames = 0;
|
||||||
@ -1423,6 +1424,7 @@ void AudioIO::SetMeters(Meter *inputMeter, Meter *outputMeter)
|
|||||||
|
|
||||||
void AudioIO::StopStream()
|
void AudioIO::StopStream()
|
||||||
{
|
{
|
||||||
|
_RPT0(_CRT_WARN, "StopStream");
|
||||||
if( mPortStreamV19 == NULL
|
if( mPortStreamV19 == NULL
|
||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
&& mMidiStream == NULL
|
&& mMidiStream == NULL
|
||||||
@ -1529,6 +1531,7 @@ void AudioIO::StopStream()
|
|||||||
mIterator->end();
|
mIterator->end();
|
||||||
delete mIterator;
|
delete mIterator;
|
||||||
mIterator = NULL; // just in case someone tries to reference it
|
mIterator = NULL; // just in case someone tries to reference it
|
||||||
|
mMidiPlaySpeed = 1.0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1678,6 +1681,8 @@ bool AudioIO::IsStreamActive()
|
|||||||
else isActive = false;
|
else isActive = false;
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
|
_RPT2(_CRT_WARN, "mMidiStreamActive %d, mMidiOutputComplete %d\n",
|
||||||
|
mMidiStreamActive, mMidiOutputComplete);
|
||||||
if( mMidiStreamActive && !mMidiOutputComplete )
|
if( mMidiStreamActive && !mMidiOutputComplete )
|
||||||
isActive = true;
|
isActive = true;
|
||||||
#endif
|
#endif
|
||||||
@ -2062,10 +2067,10 @@ MidiThread::ExitCode MidiThread::Entry()
|
|||||||
gAudioIO->FillMidiBuffers();
|
gAudioIO->FillMidiBuffers();
|
||||||
|
|
||||||
// test for end
|
// test for end
|
||||||
double real_time = gAudioIO->mT0 + gAudioIO->MidiTime() * 0.001 -
|
double realTime = gAudioIO->mT0 + gAudioIO->MidiTime() * 0.001 -
|
||||||
gAudioIO->PauseTime();
|
gAudioIO->PauseTime();
|
||||||
if (gAudioIO->mNumPlaybackChannels != 0) {
|
if (gAudioIO->mNumPlaybackChannels != 0) {
|
||||||
real_time -= 1; // with audio, MidiTime() runs ahead 1s
|
realTime -= 1; // with audio, MidiTime() runs ahead 1s
|
||||||
}
|
}
|
||||||
// The TrackPanel::OnTimer() method updates the time position
|
// The TrackPanel::OnTimer() method updates the time position
|
||||||
// indicator every 200ms, so it tends to not advance the
|
// indicator every 200ms, so it tends to not advance the
|
||||||
@ -2077,8 +2082,13 @@ MidiThread::ExitCode MidiThread::Entry()
|
|||||||
// 0.22s beyond mT1 (even though we stop playing at mT1. This
|
// 0.22s beyond mT1 (even though we stop playing at mT1. This
|
||||||
// gives OnTimer() time to wake up and draw the final time
|
// gives OnTimer() time to wake up and draw the final time
|
||||||
// position at mT1 before shutting down the stream.
|
// position at mT1 before shutting down the stream.
|
||||||
|
double timeAtSpeed = (realTime - gAudioIO->mT0) *
|
||||||
|
gAudioIO->mMidiPlaySpeed + gAudioIO->mT0;
|
||||||
|
_RPT2(_CRT_WARN, "realTime %g, timeAtSpeed %g\n",
|
||||||
|
realTime, timeAtSpeed);
|
||||||
|
|
||||||
gAudioIO->mMidiOutputComplete =
|
gAudioIO->mMidiOutputComplete =
|
||||||
(!gAudioIO->mPlayLooped && real_time >= gAudioIO->mT1 + 0.220);
|
(!gAudioIO->mPlayLooped && timeAtSpeed >= gAudioIO->mT1 + 0.220);
|
||||||
// !gAudioIO->mNextEvent);
|
// !gAudioIO->mNextEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2609,7 +2619,8 @@ void AudioIO::OutputEvent()
|
|||||||
int data2 = -1;
|
int data2 = -1;
|
||||||
|
|
||||||
// 0.0005 is for rounding
|
// 0.0005 is for rounding
|
||||||
double time = mNextEventTime + PauseTime() + 0.0005 -
|
double eventTime = (mNextEventTime - mT0) / mMidiPlaySpeed + mT0;
|
||||||
|
double time = eventTime + PauseTime() + 0.0005 -
|
||||||
((mMidiLatency + mSynthLatency) * 0.001);
|
((mMidiLatency + mSynthLatency) * 0.001);
|
||||||
if (mNumPlaybackChannels > 0) { // is there audio playback?
|
if (mNumPlaybackChannels > 0) { // is there audio playback?
|
||||||
time += 1; // MidiTime() has a 1s offset
|
time += 1; // MidiTime() has a 1s offset
|
||||||
@ -2752,7 +2763,6 @@ bool AudioIO::SetHasSolo(bool hasSolo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns estimated current track time
|
|
||||||
void AudioIO::FillMidiBuffers()
|
void AudioIO::FillMidiBuffers()
|
||||||
{
|
{
|
||||||
bool hasSolo = false;
|
bool hasSolo = false;
|
||||||
@ -2777,22 +2787,23 @@ void AudioIO::FillMidiBuffers()
|
|||||||
time = AudioTime() - PauseTime();
|
time = AudioTime() - PauseTime();
|
||||||
} else {
|
} else {
|
||||||
time = mT0 + Pt_Time() * 0.001 - PauseTime();
|
time = mT0 + Pt_Time() * 0.001 - PauseTime();
|
||||||
|
double timeAtSpeed = (time - mT0) * mMidiPlaySpeed + mT0;
|
||||||
if (mNumCaptureChannels <= 0) {
|
if (mNumCaptureChannels <= 0) {
|
||||||
// no audio callback, so move the time cursor here:
|
// no audio callback, so move the time cursor here:
|
||||||
double track_time = time - mMidiLoopOffset;
|
double trackTime = timeAtSpeed - mMidiLoopOffset;
|
||||||
//printf("mTime set. mT0 %g Pt_Time() %gs PauseTime %g\n",
|
//printf("mTime set. mT0 %g Pt_Time() %gs PauseTime %g\n",
|
||||||
// mT0, Pt_Time() * 0.001, PauseTime());
|
// mT0, Pt_Time() * 0.001, PauseTime());
|
||||||
// Since loop offset is incremented when we fill the
|
// Since loop offset is incremented when we fill the
|
||||||
// buffer, the cursor tends to jump back to mT0 early.
|
// buffer, the cursor tends to jump back to mT0 early.
|
||||||
// Therefore, if we are in loop mode, and if mTime < mT0,
|
// Therefore, if we are in loop mode, and if mTime < mT0,
|
||||||
// we must not be at the end of the loop yet.
|
// we must not be at the end of the loop yet.
|
||||||
if (mPlayLooped && track_time < mT0) {
|
if (mPlayLooped && trackTime < mT0) {
|
||||||
track_time += (mT1 - mT0);
|
trackTime += (mT1 - mT0);
|
||||||
}
|
}
|
||||||
// mTime is shared with another thread so we stored
|
// mTime is shared with another thread so we stored
|
||||||
// intermediate values in track_time. Do the update
|
// intermediate values in trackTime. Do the update
|
||||||
// atomically now that we have the final value:
|
// atomically now that we have the final value:
|
||||||
mTime = track_time;
|
mTime = trackTime;
|
||||||
}
|
}
|
||||||
// advance time so that midi messages are written a little early,
|
// advance time so that midi messages are written a little early,
|
||||||
// timestamps will insure accurate output timing. This is an "extra"
|
// timestamps will insure accurate output timing. This is an "extra"
|
||||||
@ -2802,7 +2813,7 @@ void AudioIO::FillMidiBuffers()
|
|||||||
time += MIDI_SLEEP * 0.001;
|
time += MIDI_SLEEP * 0.001;
|
||||||
}
|
}
|
||||||
while (mNextEvent &&
|
while (mNextEvent &&
|
||||||
mNextEventTime < time +
|
(mNextEventTime - mT0) / mMidiPlaySpeed + mT0 < time +
|
||||||
((MIDI_SLEEP + mSynthLatency) * 0.001)) {
|
((MIDI_SLEEP + mSynthLatency) * 0.001)) {
|
||||||
OutputEvent();
|
OutputEvent();
|
||||||
GetNextEvent();
|
GetNextEvent();
|
||||||
|
@ -157,6 +157,7 @@ class AUDACITY_DLL_API AudioIO {
|
|||||||
public:
|
public:
|
||||||
bool SetHasSolo(bool hasSolo);
|
bool SetHasSolo(bool hasSolo);
|
||||||
bool GetHasSolo() { return mHasSolo; }
|
bool GetHasSolo() { return mHasSolo; }
|
||||||
|
void SetMidiPlaySpeed(double s) { mMidiPlaySpeed = s * 0.01; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \brief Returns true if the stream is active, or even if audio I/O is
|
/** \brief Returns true if the stream is active, or even if audio I/O is
|
||||||
@ -404,6 +405,7 @@ private:
|
|||||||
PmError mLastPmError;
|
PmError mLastPmError;
|
||||||
long mMidiLatency; // latency value for PortMidi
|
long mMidiLatency; // latency value for PortMidi
|
||||||
long mSynthLatency; // latency of MIDI synthesizer
|
long mSynthLatency; // latency of MIDI synthesizer
|
||||||
|
double mMidiPlaySpeed; // a copy of TranscriptionToolBar::mPlaySpeed
|
||||||
|
|
||||||
// These fields are used to synchronize MIDI with audio
|
// These fields are used to synchronize MIDI with audio
|
||||||
volatile double mAudioCallbackOutputTime; // PortAudio's outTime
|
volatile double mAudioCallbackOutputTime; // PortAudio's outTime
|
||||||
|
@ -5101,6 +5101,7 @@ void AudacityProject::OnScoreAlign()
|
|||||||
int numNoteTracksSelected = 0;
|
int numNoteTracksSelected = 0;
|
||||||
int numOtherTracksSelected = 0;
|
int numOtherTracksSelected = 0;
|
||||||
NoteTrack *nt;
|
NoteTrack *nt;
|
||||||
|
NoteTrack *alignedNoteTrack;
|
||||||
double endTime = 0.0;
|
double endTime = 0.0;
|
||||||
|
|
||||||
// Iterate through once to make sure that there is exactly
|
// Iterate through once to make sure that there is exactly
|
||||||
@ -5136,16 +5137,28 @@ void AudacityProject::OnScoreAlign()
|
|||||||
if (params.mStatus != wxID_OK) return;
|
if (params.mStatus != wxID_OK) return;
|
||||||
|
|
||||||
// We're going to do it.
|
// We're going to do it.
|
||||||
PushState(_("Sync MIDI with Audio"), _("Sync MIDI with Audio"));
|
//pushing the state before the change is wrong (I think)
|
||||||
|
//PushState(_("Sync MIDI with Audio"), _("Sync MIDI with Audio"));
|
||||||
|
// Make a copy of the note track in case alignment is canceled or fails
|
||||||
|
alignedNoteTrack = (NoteTrack *) nt->Duplicate();
|
||||||
|
// Duplicate() on note tracks serializes seq to a buffer, but we need
|
||||||
|
// the seq, so Duplicate again and discard the track with buffer. The
|
||||||
|
// test is here in case Duplicate() is changed in the future.
|
||||||
|
if (alignedNoteTrack->GetSequence() == NULL) {
|
||||||
|
NoteTrack *temp = (NoteTrack *) alignedNoteTrack->Duplicate();
|
||||||
|
delete alignedNoteTrack;
|
||||||
|
alignedNoteTrack = temp;
|
||||||
|
assert(alignedNoteTrack->GetSequence());
|
||||||
|
}
|
||||||
// Remove offset from NoteTrack because audio is
|
// Remove offset from NoteTrack because audio is
|
||||||
// mixed starting at zero and incorporating clip offsets.
|
// mixed starting at zero and incorporating clip offsets.
|
||||||
if (nt->GetOffset() < 0) {
|
if (alignedNoteTrack->GetOffset() < 0) {
|
||||||
// remove the negative offset data before alignment
|
// remove the negative offset data before alignment
|
||||||
nt->Clear(nt->GetOffset(), 0);
|
nt->Clear(alignedNoteTrack->GetOffset(), 0);
|
||||||
} else if (nt->GetOffset() > 0) {
|
} else if (alignedNoteTrack->GetOffset() > 0) {
|
||||||
nt->Shift(nt->GetOffset());
|
alignedNoteTrack->Shift(alignedNoteTrack->GetOffset());
|
||||||
}
|
}
|
||||||
nt->SetOffset(0);
|
alignedNoteTrack->SetOffset(0);
|
||||||
|
|
||||||
WaveTrack **waveTracks;
|
WaveTrack **waveTracks;
|
||||||
mTracks->GetWaveTracks(true /* selectionOnly */,
|
mTracks->GetWaveTracks(true /* selectionOnly */,
|
||||||
@ -5176,7 +5189,7 @@ void AudacityProject::OnScoreAlign()
|
|||||||
#ifndef SKIP_ACTUAL_SCORE_ALIGNMENT
|
#ifndef SKIP_ACTUAL_SCORE_ALIGNMENT
|
||||||
int result = scorealign((void *) mix, &mixer_process,
|
int result = scorealign((void *) mix, &mixer_process,
|
||||||
2 /* channels */, 44100.0 /* srate */, endTime,
|
2 /* channels */, 44100.0 /* srate */, endTime,
|
||||||
nt->GetSequence(), progress, params);
|
alignedNoteTrack->GetSequence(), progress, params);
|
||||||
#else
|
#else
|
||||||
int result = SA_SUCCESS;
|
int result = SA_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
@ -5185,22 +5198,27 @@ void AudacityProject::OnScoreAlign()
|
|||||||
delete mix;
|
delete mix;
|
||||||
|
|
||||||
if (result == SA_SUCCESS) {
|
if (result == SA_SUCCESS) {
|
||||||
|
mTracks->Replace(nt, alignedNoteTrack, true);
|
||||||
RedrawProject();
|
RedrawProject();
|
||||||
wxMessageBox(wxString::Format(
|
wxMessageBox(wxString::Format(
|
||||||
_("Alignment completed: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs."),
|
_("Alignment completed: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs."),
|
||||||
params.mMidiStart, params.mMidiEnd,
|
params.mMidiStart, params.mMidiEnd,
|
||||||
params.mAudioStart, params.mAudioEnd));
|
params.mAudioStart, params.mAudioEnd));
|
||||||
|
PushState(_("Sync MIDI with Audio"), _("Sync MIDI with Audio"));
|
||||||
} else if (result == SA_TOOSHORT) {
|
} else if (result == SA_TOOSHORT) {
|
||||||
|
delete alignedNoteTrack;
|
||||||
wxMessageBox(wxString::Format(
|
wxMessageBox(wxString::Format(
|
||||||
_("Alignment error: input too short: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs."),
|
_("Alignment error: input too short: MIDI from %.2f to %.2f secs, Audio from %.2f to %.2f secs."),
|
||||||
params.mMidiStart, params.mMidiEnd,
|
params.mMidiStart, params.mMidiEnd,
|
||||||
params.mAudioStart, params.mAudioEnd));
|
params.mAudioStart, params.mAudioEnd));
|
||||||
} else if (result == SA_CANCEL) {
|
} else if (result == SA_CANCEL) {
|
||||||
GetActiveProject()->OnUndo(); // recover any changes to note track
|
// wrong way to recover...
|
||||||
|
//GetActiveProject()->OnUndo(); // recover any changes to note track
|
||||||
|
delete alignedNoteTrack;
|
||||||
return; // no message when user cancels alignment
|
return; // no message when user cancels alignment
|
||||||
} else {
|
} else {
|
||||||
GetActiveProject()->OnUndo(); // recover any changes to note track
|
//GetActiveProject()->OnUndo(); // recover any changes to note track
|
||||||
|
delete alignedNoteTrack;
|
||||||
wxMessageBox(_("Internal error reported by alignment process."));
|
wxMessageBox(_("Internal error reported by alignment process."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -871,6 +871,8 @@ void TrackPanel::OnTimer()
|
|||||||
wxCommandEvent dummyEvent;
|
wxCommandEvent dummyEvent;
|
||||||
AudacityProject *p = GetProject();
|
AudacityProject *p = GetProject();
|
||||||
|
|
||||||
|
static int rptcnt = 0;
|
||||||
|
_RPT1(_CRT_WARN, "OnTimer %d\n", rptcnt++);
|
||||||
if ((p->GetAudioIOToken() > 0) &&
|
if ((p->GetAudioIOToken() > 0) &&
|
||||||
gAudioIO->IsStreamActive(p->GetAudioIOToken()))
|
gAudioIO->IsStreamActive(p->GetAudioIOToken()))
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,9 @@ void MidiIOPrefs::Populate()
|
|||||||
|
|
||||||
// Get current setting for devices
|
// Get current setting for devices
|
||||||
mPlayDevice = gPrefs->Read(wxT("/MidiIO/PlaybackDevice"), wxT(""));
|
mPlayDevice = gPrefs->Read(wxT("/MidiIO/PlaybackDevice"), wxT(""));
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
mRecordDevice = gPrefs->Read(wxT("/MidiIO/RecordingDevice"), wxT(""));
|
mRecordDevice = gPrefs->Read(wxT("/MidiIO/RecordingDevice"), wxT(""));
|
||||||
|
#endif
|
||||||
// mRecordChannels = gPrefs->Read(wxT("/MidiIO/RecordChannels"), 2L);
|
// mRecordChannels = gPrefs->Read(wxT("/MidiIO/RecordChannels"), 2L);
|
||||||
|
|
||||||
//------------------------- Main section --------------------
|
//------------------------- Main section --------------------
|
||||||
@ -147,7 +149,7 @@ void MidiIOPrefs::PopulateOrExchange( ShuttleGui & S ) {
|
|||||||
S.EndMultiColumn();
|
S.EndMultiColumn();
|
||||||
}
|
}
|
||||||
S.EndStatic();
|
S.EndStatic();
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
S.StartStatic(_("Recording"));
|
S.StartStatic(_("Recording"));
|
||||||
{
|
{
|
||||||
S.StartMultiColumn(2);
|
S.StartMultiColumn(2);
|
||||||
@ -167,6 +169,7 @@ void MidiIOPrefs::PopulateOrExchange( ShuttleGui & S ) {
|
|||||||
S.EndMultiColumn();
|
S.EndMultiColumn();
|
||||||
}
|
}
|
||||||
S.EndStatic();
|
S.EndStatic();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiIOPrefs::OnHost(wxCommandEvent & e)
|
void MidiIOPrefs::OnHost(wxCommandEvent & e)
|
||||||
@ -182,7 +185,9 @@ void MidiIOPrefs::OnHost(wxCommandEvent & e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mPlay->Clear();
|
mPlay->Clear();
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
mRecord->Clear();
|
mRecord->Clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
wxArrayString playnames;
|
wxArrayString playnames;
|
||||||
wxArrayString recordnames;
|
wxArrayString recordnames;
|
||||||
@ -204,7 +209,7 @@ void MidiIOPrefs::OnHost(wxCommandEvent & e)
|
|||||||
mPlay->SetSelection(index);
|
mPlay->SetSelection(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
if (info->input) {
|
if (info->input) {
|
||||||
recordnames.Add(name);
|
recordnames.Add(name);
|
||||||
index = mRecord->Append(name, (void *) info);
|
index = mRecord->Append(name, (void *) info);
|
||||||
@ -212,6 +217,7 @@ void MidiIOPrefs::OnHost(wxCommandEvent & e)
|
|||||||
mRecord->SetSelection(index);
|
mRecord->SetSelection(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,23 +225,25 @@ void MidiIOPrefs::OnHost(wxCommandEvent & e)
|
|||||||
playnames.Add(_("No devices found"));
|
playnames.Add(_("No devices found"));
|
||||||
mPlay->Append(playnames[0], (void *) NULL);
|
mPlay->Append(playnames[0], (void *) NULL);
|
||||||
}
|
}
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
if (mRecord->GetCount() == 0) {
|
if (mRecord->GetCount() == 0) {
|
||||||
recordnames.Add(_("No devices found"));
|
recordnames.Add(_("No devices found"));
|
||||||
mRecord->Append(recordnames[0], (void *) NULL);
|
mRecord->Append(recordnames[0], (void *) NULL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (mPlay->GetCount() && mPlay->GetSelection() == wxNOT_FOUND) {
|
if (mPlay->GetCount() && mPlay->GetSelection() == wxNOT_FOUND) {
|
||||||
mPlay->SetSelection(0);
|
mPlay->SetSelection(0);
|
||||||
}
|
}
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
if (mRecord->GetCount() && mRecord->GetSelection() == wxNOT_FOUND) {
|
if (mRecord->GetCount() && mRecord->GetSelection() == wxNOT_FOUND) {
|
||||||
mRecord->SetSelection(0);
|
mRecord->SetSelection(0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
ShuttleGui S(this, eIsCreating);
|
ShuttleGui S(this, eIsCreating);
|
||||||
S.SetSizeHints(mPlay, playnames);
|
S.SetSizeHints(mPlay, playnames);
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
S.SetSizeHints(mRecord, recordnames);
|
S.SetSizeHints(mRecord, recordnames);
|
||||||
|
#endif
|
||||||
// OnDevice(e);
|
// OnDevice(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +261,7 @@ bool MidiIOPrefs::Apply()
|
|||||||
wxString(info->interf, wxConvLocal).c_str(),
|
wxString(info->interf, wxConvLocal).c_str(),
|
||||||
wxString(info->name, wxConvLocal).c_str()));
|
wxString(info->name, wxConvLocal).c_str()));
|
||||||
}
|
}
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
info = (const PmDeviceInfo *) mRecord->GetClientData(mRecord->GetSelection());
|
info = (const PmDeviceInfo *) mRecord->GetClientData(mRecord->GetSelection());
|
||||||
if (info) {
|
if (info) {
|
||||||
gPrefs->Write(wxT("/MidiIO/RecordingDevice"),
|
gPrefs->Write(wxT("/MidiIO/RecordingDevice"),
|
||||||
@ -261,7 +269,7 @@ bool MidiIOPrefs::Apply()
|
|||||||
wxString(info->interf, wxConvLocal).c_str(),
|
wxString(info->interf, wxConvLocal).c_str(),
|
||||||
wxString(info->name, wxConvLocal).c_str()));
|
wxString(info->name, wxConvLocal).c_str()));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,13 +45,17 @@ class MidiIOPrefs:public PrefsPanel
|
|||||||
wxArrayString mHostLabels;
|
wxArrayString mHostLabels;
|
||||||
|
|
||||||
wxString mPlayDevice;
|
wxString mPlayDevice;
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
wxString mRecordDevice;
|
wxString mRecordDevice;
|
||||||
|
#endif
|
||||||
// long mRecordChannels;
|
// long mRecordChannels;
|
||||||
|
|
||||||
wxChoice *mHost;
|
wxChoice *mHost;
|
||||||
wxChoice *mPlay;
|
wxChoice *mPlay;
|
||||||
wxTextCtrl *mLatency;
|
wxTextCtrl *mLatency;
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_IN
|
||||||
wxChoice *mRecord;
|
wxChoice *mRecord;
|
||||||
|
#endif
|
||||||
// wxChoice *mChannels;
|
// wxChoice *mChannels;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE();
|
DECLARE_EVENT_TABLE();
|
||||||
|
@ -415,7 +415,9 @@ void TranscriptionToolBar::OnPlaySpeed(wxCommandEvent & event)
|
|||||||
// Start playing
|
// Start playing
|
||||||
if (playRegionStart >= 0) {
|
if (playRegionStart >= 0) {
|
||||||
// playRegionEnd = playRegionStart + (playRegionEnd-playRegionStart)* 100.0/mPlaySpeed;
|
// playRegionEnd = playRegionStart + (playRegionEnd-playRegionStart)* 100.0/mPlaySpeed;
|
||||||
|
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||||
|
gAudioIO->SetMidiPlaySpeed(mPlaySpeed);
|
||||||
|
#endif
|
||||||
p->GetControlToolBar()->PlayPlayRegion(playRegionStart,
|
p->GetControlToolBar()->PlayPlayRegion(playRegionStart,
|
||||||
playRegionEnd,
|
playRegionEnd,
|
||||||
false,
|
false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user