From: <rel...@us...> - 2009-08-20 16:46:20
|
Revision: 335 http://modplug.svn.sourceforge.net/modplug/?rev=335&view=rev Author: relabsoluness Date: 2009-08-20 16:46:12 +0000 (Thu, 20 Aug 2009) Log Message: ----------- [New] MIDI: Can now record MIDI mapping changes to pattern. Modified Paths: -------------- trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp trunk/OpenMPT/mptrack/MIDIMappingDialog.h trunk/OpenMPT/mptrack/Mpt_midi.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_pat.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/midi.h trunk/OpenMPT/soundlib/modcommand.h Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-20 16:46:12 UTC (rev 335) @@ -52,6 +52,7 @@ ON_BN_CLICKED(IDC_BUTTON_REMOVE, OnBnClickedButtonRemove) ON_MESSAGE(WM_MOD_MIDIMSG, OnMidiMsg) ON_NOTIFY(UDN_DELTAPOS, IDC_SPINMOVEMAPPING, OnDeltaposSpinmovemapping) + ON_BN_CLICKED(IDC_CHECK_PATRECORD, OnBnClickedCheckPatRecord) END_MESSAGE_MAP() @@ -77,10 +78,15 @@ { CDialog::OnInitDialog(); + if (m_rMIDIMapper.GetCount() > 0) + m_Setting = m_rMIDIMapper.GetDirective(0); + m_ChannelCBox.SetCurSel(m_Setting.GetChannel()); - CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? MF_CHECKED : MF_UNCHECKED); - CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? MF_CHECKED : MF_UNCHECKED); + CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED); + GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE); + CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED); m_EventCBox.SetCurSel(0); @@ -168,6 +174,14 @@ } +void CMIDIMappingDialog::OnBnClickedCheckPatRecord() +//-------------------------------------------------- +{ + m_Setting.SetAllowPatternEdit(IsDlgButtonChecked(IDC_CHECK_PATRECORD) == BST_CHECKED); + UpdateString(); +} + + void CMIDIMappingDialog::UpdateString() //------------------------------------- { Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.h =================================================================== --- trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-20 16:46:12 UTC (rev 335) @@ -65,4 +65,5 @@ afx_msg void OnBnClickedButtonRemove(); afx_msg LRESULT OnMidiMsg(WPARAM, LPARAM); afx_msg void OnDeltaposSpinmovemapping(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedCheckPatRecord(); }; Modified: trunk/OpenMPT/mptrack/Mpt_midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-20 16:46:12 UTC (rev 335) @@ -192,7 +192,8 @@ uint8 temp8 = citer->IsActive(); //bit 0 if(citer->GetCaptureMIDI()) temp8 |= (1 << 1); //bit 1 //bits 2-4: Mapping type: 0 for plug param control. - //bit 5: if(citer->GetAllowPatternEdit()) temp8 |= (1 << 4); + //bit 5: + if(citer->GetAllowPatternEdit()) temp8 |= (1 << 5); //bits 6-7: Size: 5, 6, 8, 12 BYTE parambytes = 4; @@ -238,7 +239,7 @@ CMIDIMappingDirective s; s.SetActive((i8 & 1) != 0); s.SetCaptureMIDI((i8 & (1 << 1)) != 0); - s.SetAllowPatternEdit((i8 & (1 << 4)) != 0); + s.SetAllowPatternEdit((i8 & (1 << 5)) != 0); memcpy(&i16, ptr, 2); ptr += 2; //Channel, event, MIDIbyte1. memcpy(&i8, ptr, 1); ptr++; //Plugindex const BYTE remainingbytes = psize - 4; Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-20 16:46:12 UTC (rev 335) @@ -3001,6 +3001,30 @@ } +ModCommandPos CViewPattern::GetEditPos(CSoundFile& rSf, const bool bLiveRecord) const +//----------------------------------------------------------------------------------- +{ + ModCommandPos editpos; + if(bLiveRecord) + SetEditPos(rSf, editpos.nRow, editpos.nPat, rSf.m_nRow, rSf.m_nPattern); + else + {editpos.nPat = m_nPattern; editpos.nRow = m_nRow;} + editpos.nChn = GetChanFromCursor(m_dwCursor); + return editpos; +} + + +MODCOMMAND* CViewPattern::GetModCommand(CSoundFile& rSf, const ModCommandPos& pos) +//-------------------------------------------------------------------------------- +{ + static MODCOMMAND m; + if (rSf.Patterns.IsValidIndex(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels()) + return rSf.Patterns[pos.nPat].GetpModCommand(pos.nRow, pos.nChn); + else + return &m; +} + + LRESULT CViewPattern::OnMidiMsg(WPARAM dwMidiDataParam, LPARAM) //-------------------------------------------------------- { @@ -3043,10 +3067,25 @@ if ((event == 0x9) && !nVol) event = 0x8; //Convert event to note-off if req'd - //Try finding MIDI mapping. - BYTE mappedIndex = 0, paramValue = 0; + // Handle MIDI mapping. + uint8 mappedIndex = uint8_max, paramValue = uint8_max; uint32 paramIndex = 0; - if(pSndFile->GetMIDIMapper().OnMIDImsg(dwMidiData, mappedIndex, paramIndex, paramValue)) + const bool bCaptured = pSndFile->GetMIDIMapper().OnMIDImsg(dwMidiData, mappedIndex, paramIndex, paramValue); + + // Write parameter control commands if needed. + if (paramValue != uint8_max && IsEditingEnabled() && pSndFile->GetType() == MOD_TYPE_MPT) + { + // Note: There's no undo for these modifications. + const bool bLiveRecord = IsLiveRecord(*pModDoc, *pSndFile); + ModCommandPos editpos = GetEditPos(*pSndFile, bLiveRecord); + MODCOMMAND* p = GetModCommand(*pSndFile, editpos); + p->Set(NOTE_PCS, mappedIndex, static_cast<uint16>(paramIndex), static_cast<uint16>((paramValue * MODCOMMAND::maxColumnValue)/127)); + if(bLiveRecord == false) + InvalidateRow(editpos.nRow); + pMainFrm->ThreadSafeSetModified(pModDoc); + } + + if (bCaptured) return 0; switch(event) @@ -3079,17 +3118,13 @@ } // Checking whether to record MIDI controller change as MIDI macro change. - if((CMainFrame::m_dwMidiSetup & MIDISETUP_MIDIMACROCONTROL) && IsEditingEnabled()) + // Don't write this if command was already written by MIDI mapping. + if((paramValue == uint8_max || pSndFile->GetType() != MOD_TYPE_MPT) && IsEditingEnabled() && (CMainFrame::m_dwMidiSetup & MIDISETUP_MIDIMACROCONTROL)) { - // Note: No undo for these modifications. + // Note: There's no undo for these modifications. const bool bLiveRecord = IsLiveRecord(*pModDoc, *pSndFile); - ROWINDEX nRow = m_nRow; - PATTERNINDEX nPat = m_nPattern; - if(bLiveRecord) - SetEditPos(*pSndFile, nRow, nPat, pSndFile->m_nRow, pSndFile->m_nPattern); - - const CHANNELINDEX nChn = GetChanFromCursor(m_dwCursor); - MODCOMMAND *p = pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn); + ModCommandPos editpos = GetEditPos(*pSndFile, bLiveRecord); + MODCOMMAND* p = GetModCommand(*pSndFile, editpos); if(p->command == 0 || p->command == CMD_SMOOTHMIDI || p->command == CMD_MIDI) { // Write command only if there's no existing command or already a midi macro command. p->command = CMD_SMOOTHMIDI; @@ -3098,7 +3133,7 @@ // Update GUI only if not recording live. if(bLiveRecord == false) - InvalidateRow(nRow); + InvalidateRow(editpos.nRow); } } @@ -4941,20 +4976,15 @@ return chans.GetCount(); } -UINT CViewPattern::GetRowFromCursor(DWORD cursor) { -//----------------------------------------------- - return cursor >> 16; -} +ROWINDEX CViewPattern::GetRowFromCursor(DWORD cursor) {return cursor >> 16;} +//--------------------------------------------------- + +CHANNELINDEX CViewPattern::GetChanFromCursor(DWORD cursor) {return static_cast<CHANNELINDEX>((cursor & 0xFFFF) >> 3);} +//------------------------------------------------------- -UINT CViewPattern::GetChanFromCursor(DWORD cursor) { -//------------------------------------------------ - return (cursor & 0xFFFF) >> 3; -} +UINT CViewPattern::GetColTypeFromCursor(DWORD cursor) {return cursor & 0x07;} +//--------------------------------------------------- -UINT CViewPattern::GetColTypeFromCursor(DWORD cursor) { -//-------------------------------------------------- - return cursor & 0x07; -} bool CViewPattern::IsInterpolationPossible(UINT startRow, UINT endRow, UINT chan, UINT colType, CSoundFile* pSndFile) { Modified: trunk/OpenMPT/mptrack/View_pat.h =================================================================== --- trunk/OpenMPT/mptrack/View_pat.h 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/mptrack/View_pat.h 2009-08-20 16:46:12 UTC (rev 335) @@ -55,7 +55,14 @@ }; const RowMask DefaultRowMask = {true, true, true, true, true}; +struct ModCommandPos +{ + PATTERNINDEX nPat; + ROWINDEX nRow; + CHANNELINDEX nChn; +}; + ////////////////////////////////////////////////////////////////// // Pattern editing class @@ -323,9 +330,9 @@ UINT GetSelectionEndChan(); UINT ListChansWhereColSelected(UINT colType, CArray<UINT,UINT> &chans); - UINT GetRowFromCursor(DWORD cursor); - UINT GetChanFromCursor(DWORD cursor); - UINT GetColTypeFromCursor(DWORD cursor); + static ROWINDEX GetRowFromCursor(DWORD cursor); + static CHANNELINDEX GetChanFromCursor(DWORD cursor); + static UINT GetColTypeFromCursor(DWORD cursor); bool IsInterpolationPossible(UINT startRow, UINT endRow, UINT chan, UINT colType, CSoundFile* pSndFile); void Interpolate(UINT type); @@ -341,6 +348,13 @@ ROWINDEX& iRow, PATTERNINDEX& iPat, const ROWINDEX iRowCandidate, const PATTERNINDEX iPatCandidate) const; + // Returns edit position. + ModCommandPos GetEditPos(CSoundFile& rSf, const bool bLiveRecord) const; + + // Returns pointer to modcommand at given position. If the position is not valid, returns pointer + // to a dummy command. + MODCOMMAND* GetModCommand(CSoundFile& rSf, const ModCommandPos& pos); + bool IsEditingEnabled() const {return ((m_dwStatus&PATSTATUS_RECORD) != 0);} //Like IsEditingEnabled(), but shows some notification when editing is not enabled. Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-08-20 16:46:12 UTC (rev 335) @@ -2248,7 +2248,7 @@ BEGIN GROUPBOX "Current mapping",IDC_STATIC,5,5,325,105 CONTROL "Active",IDC_CHECKACTIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,20,42,10 - CONTROL "Capture",IDC_CHECKCAPTURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,20,39,10 + CONTROL "Capture",IDC_CHECKCAPTURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,67,20,39,10 LTEXT "Channel",IDC_STATIC,15,35,27,8 COMBOBOX IDC_COMBO_CHANNEL,15,45,36,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Event",IDC_STATIC,61,35,20,8 @@ -2267,6 +2267,7 @@ CONTROL "",IDC_SPINMOVEMAPPING,"msctls_updown32",0x0,330,115,11,80 CONTROL "MIDI learn",IDC_CHECK_MIDILEARN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,335,30,47,11 DEFPUSHBUTTON "Close",IDOK,335,10,50,14 + CONTROL "Pattern record",IDC_CHECK_PATRECORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,114,20,63,10 END IDD_TUNING DIALOGEX 0, 0, 512, 240 Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/mptrack/resource.h 2009-08-20 16:46:12 UTC (rev 335) @@ -882,6 +882,7 @@ #define IDC_SPIN_ADDSILENCE 2382 #define IDC_RADIO_RESIZETO 2384 #define IDC_EDIT_MODLOADING_WARNINGS 2385 +#define IDC_CHECK_PATRECORD 2386 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1123,7 +1124,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 521 #define _APS_NEXT_COMMAND_VALUE 59229 -#define _APS_NEXT_CONTROL_VALUE 2386 +#define _APS_NEXT_CONTROL_VALUE 2387 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/soundlib/midi.h =================================================================== --- trunk/OpenMPT/soundlib/midi.h 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/soundlib/midi.h 2009-08-20 16:46:12 UTC (rev 335) @@ -68,10 +68,10 @@ CString ToString() const { CString str; str.Preallocate(20); - char flags[3] = "00"; + char flags[4] = "000"; if(m_Active) flags[0] = '1'; if(m_CaptureMIDI) flags[1] = '1'; - //if(m_AllowPatternEdit) flags[2] = '1'; + if(m_AllowPatternEdit) flags[2] = '1'; str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter); str.Trim(); return str; Modified: trunk/OpenMPT/soundlib/modcommand.h =================================================================== --- trunk/OpenMPT/soundlib/modcommand.h 2009-08-19 15:20:48 UTC (rev 334) +++ trunk/OpenMPT/soundlib/modcommand.h 2009-08-20 16:46:12 UTC (rev 335) @@ -31,6 +31,8 @@ return !(*this == mc); } + void Set(NOTE n, INSTR ins, uint16 volcol, uint16 effectcol) {note = n; instr = ins; SetValueVolCol(volcol); SetValueEffectCol(effectcol);} + uint16 GetValueVolCol() const {return GetValueVolCol(volcmd, vol);} static uint16 GetValueVolCol(BYTE volcmd, BYTE vol) {return (volcmd << 8) + vol;} void SetValueVolCol(const uint16 val) {volcmd = static_cast<BYTE>(val >> 8); vol = static_cast<BYTE>(val & 0xFF);} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |