yfMIDIKeyboardPanel::yfMIDIKeyboardPanel(yfMIDIOutDevice& outdevice, wxWindow* parent, wxWindowID id) : wxPanel(parent, id), m_outdevice(outdevice) { wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); CreateKeyPanel(topsizer); CreateSubPanel(topsizer); SetSizer(topsizer); topsizer->SetSizeHints(this); } void yfMIDIKeyboardPanel::CreateKeyPanel(wxSizer* sizer) { m_tone.SetIndexC3(IDC_C3_BUTTON); wxStaticBox* staticbox = new wxStaticBox(this, -1, wxT("")); wxStaticBoxSizer* frame = new wxStaticBoxSizer(staticbox, wxVERTICAL); wxBoxSizer* black = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* white = new wxBoxSizer(wxHORIZONTAL); CreateHideButton(REDUCE_HALF, black); CreateToneButton(IDC_C2_BUTTON, white); CreateToneButton(IDC_CS2_BUTTON, black); CreateToneButton(IDC_D2_BUTTON, white); CreateToneButton(IDC_DS2_BUTTON, black); CreateToneButton(IDC_E2_BUTTON, white); //途中省略 frame->Add(black,1,wxALIGN_CENTRE|wxALL|wxEXPAND); frame->Add(white,1,wxALIGN_CENTRE|wxALL|wxEXPAND); sizer->Add(frame,1,wxALIGN_CENTRE|wxALL|wxEXPAND,2); } void yfMIDIKeyboardPanel::CreateToneButton(UINT id, wxSizer* sizer) { yfDoubleEventButton* button = new yfDoubleEventButton(this, id, m_tone.GetCaptureFromIndex(id)); button->SetSizeHints(26,-1); button->SetDownEvent(EVT_TONE_BUTTON_DOWN); button->SetUpEvent(EVT_TONE_BUTTON_UP); sizer->Add(button,2,wxALIGN_CENTRE_VERTICAL|wxALL,2); } void yfMIDIKeyboardPanel::CreateHideButton(UINT reduce, wxSizer* sizer) { wxWindow* window = new wxWindow(this, -1); window->SetSizeHints(26/reduce,-1); sizer->Add(window,2/reduce,wxALIGN_CENTRE_VERTICAL|wxALL,2/reduce); } |
EVT_COMMAND_RANGE(IDC_C2_BUTTON, IDC_B4_BUTTON, EVT_TONE_BUTTON_DOWN, yfMIDIKeyboardPanel::OnToneButtonDown) |
class yfMIDINoteNumber { int m_octave; unsigned m_index; public: const static unsigned NOTE_CENTER = 60; const static unsigned OCTAVE_CENTER = 3; yfMIDINoteNumber(); static wxString GetCapture(unsigned tone); static wxString GetNoteCapture(unsigned tone); static wxString GetOctaveCapture(unsigned tone); static int ToOctave(unsigned tone); static unsigned ToNoteOffset(unsigned tone); //octave void SetOctaveShift(int octave); int GetOctaveShift(void) const; unsigned OctaveShift(unsigned tone) const; //index void SetIndexC3(unsigned index); unsigned GetIndexC3(unsigned index) const; unsigned GetNoteNumber(unsigned index) const; wxString GetCaptureFromIndex(unsigned index) const; }; |
yfMIDINoteNumber::yfMIDINoteNumber() : m_octave(0), m_index(NOTE_CENTER) { } wxString yfMIDINoteNumber::GetCapture(unsigned tone) { return GetNoteCapture(tone) + GetOctaveCapture(tone); } wxString yfMIDINoteNumber::GetNoteCapture(unsigned tone) { const static wxString capture[] = { wxT("C"), wxT("C#"), wxT("D"), wxT("D#"), wxT("E"), wxT("F"), wxT("F#"), wxT("G"), wxT("G#"), wxT("A"), wxT("A#"), wxT("B") }; return capture[ToNoteOffset(tone)]; } wxString yfMIDINoteNumber::GetOctaveCapture(unsigned tone) { return wxString::Format(wxT("%d"), ToOctave(tone)); } int yfMIDINoteNumber::ToOctave(unsigned tone) { if(tone>127) tone = 127; return tone / 12 - 2; } unsigned yfMIDINoteNumber::ToNoteOffset(unsigned tone) { return tone % 12; } //octave void yfMIDINoteNumber::SetOctaveShift(int octave) { m_octave = octave; } int yfMIDINoteNumber::GetOctaveShift(void) const { return m_octave; } unsigned yfMIDINoteNumber::OctaveShift(unsigned tone) const { int value; if(tone>127) value = 127; else value = tone; value += m_octave*12; if(value<0) value = 0; if(value>127) value = 127; return value; } //index void yfMIDINoteNumber::SetIndexC3(unsigned index) { m_index = index; } unsigned yfMIDINoteNumber::GetIndexC3(unsigned index) const { return m_index; } unsigned yfMIDINoteNumber::GetNoteNumber(unsigned index) const { long value = (long)index - (long)m_index + NOTE_CENTER; if(value<0) value = 0; if(value>127) value = 127; return OctaveShift(value); } wxString yfMIDINoteNumber::GetCaptureFromIndex(unsigned index) const { return GetCapture(GetNoteNumber(index)); } |
void yfMIDIKeyboardPanel::CreateSubPanel(wxSizer* sizer) { wxBoxSizer* frame = new wxBoxSizer(wxHORIZONTAL); m_velocitySlider = new yfSlideValue(this, IDC_SLIDER_VELOCITY, wxT("Velocity"), 127, 0, 127); m_velocitySlider->GetSlider()->SetPageSize(16); frame->Add(m_velocitySlider,3,wxALIGN_CENTRE_VERTICAL); m_offVelocitySlider = new yfSlideValue(this, IDC_SLIDER_OFF_VELOCITY, wxT("Off velocity"), 127, 0, 127); m_offVelocitySlider->GetSlider()->SetPageSize(16); frame->Add(m_offVelocitySlider,2,wxALIGN_CENTRE_VERTICAL); m_octaveSlider = new yfSlideValue(this, IDC_SLIDER_OCTAVE, wxT("Octave"), 3, 0, 7); m_octaveSlider->GetSlider()->SetPageSize(1); frame->Add(m_octaveSlider,2,wxALIGN_CENTRE_VERTICAL); wxBoxSizer* subframe = new wxBoxSizer(wxVERTICAL); //channel wxStaticText* statcText = new wxStaticText(this, -1, wxT("Channel")); subframe->Add(statcText,1,wxALIGN_CENTRE_VERTICAL|wxEXPAND|wxALL,10); m_channelBox = new wxComboBox(this, -1, wxT("Channel")); for(int i=1; i<=16; i++){ m_channelBox->Append( wxString::Format(wxT("%d"),i) ); } m_channelBox->SetSelection(0); subframe->Add(m_channelBox,1,wxEXPAND|wxALL,10); frame->Add(subframe,1,wxALIGN_CENTRE_VERTICAL|wxEXPAND); sizer->Add(frame,1,wxALIGN_CENTRE|wxEXPAND); } |
class yfMIDIDataMaker { public: static DWORD NoteOn(int channel, int note, int velocity); static DWORD NoteOff(int channel, int note, int velocity); }; |
inline static void Limit(int& value, int min, int max) { if(value<min) value = min; if(value>max) value = max; } inline static DWORD ShortMsg(BYTE status, BYTE data1, BYTE data2) { return MAKELONG(MAKEWORD(status,data1),MAKEWORD(data2,0)); } inline static DWORD ShortMsg(BYTE data1, BYTE data2) { return MAKELONG(MAKEWORD(data1,data2),MAKEWORD(0,0)); } DWORD yfMIDIDataMaker::NoteOn(int channel, int note, int velocity) { Limit(channel,1,16); Limit(note,0,127); Limit(velocity,0,127); return ShortMsg(0x90|channel-1, note, velocity); } DWORD yfMIDIDataMaker::NoteOff(int channel, int note, int velocity) { Limit(channel,1,16); Limit(note,0,127); Limit(velocity,0,127); return ShortMsg(0x80|channel-1, note, velocity); } |
void yfMIDIKeyboardPanel::OnToneButtonDown(wxCommandEvent& event) { try{ m_note.SetOctave(GetOctave()-yfMIDINoteNumber::OCTAVE_CENTER); unsigned noteNumber = m_note.GetNoteNumber(event.GetId()); m_outdevice.OutShortMsg( yfMIDIDataMaker::NoteOn(GetChannel(), noteNumber, GetVelocity()) ); }catch(...){ ::wxMessageBox(wxT("OutShortMsg - error ???")); }; } |