1 /*
2  * MidiController.cpp - implementation of class midi-controller which handles
3  *                      MIDI control change messages
4  *
5  * Copyright (c) 2008 Paul Giblock <drfaygo/at/gmail.com>
6  *
7  * This file is part of LMMS - https://lmms.io
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public
20  * License along with this program (see COPYING); if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301 USA.
23  *
24  */
25 
26 #include <QDomElement>
27 #include <QObject>
28 
29 #include "Song.h"
30 #include "Mixer.h"
31 #include "MidiClient.h"
32 #include "MidiController.h"
33 
34 
MidiController(Model * _parent)35 MidiController::MidiController( Model * _parent ) :
36 	Controller( Controller::MidiController, _parent, tr( "MIDI Controller" ) ),
37 	MidiEventProcessor(),
38 	m_midiPort( tr( "unnamed_midi_controller" ),
39 			Engine::mixer()->midiClient(), this, this, MidiPort::Input ),
40 	m_lastValue( 0.0f ),
41 	m_previousValue( 0.0f )
42 {
43 	setSampleExact( true );
44 	connect( &m_midiPort, SIGNAL( modeChanged() ),
45 			this, SLOT( updateName() ) );
46 }
47 
48 
49 
50 
~MidiController()51 MidiController::~MidiController()
52 {
53 }
54 
55 
56 
57 
updateValueBuffer()58 void MidiController::updateValueBuffer()
59 {
60 	if( m_previousValue != m_lastValue )
61 	{
62 		m_valueBuffer.interpolate( m_previousValue, m_lastValue );
63 		m_previousValue = m_lastValue;
64 	}
65 	else
66 	{
67 		m_valueBuffer.fill( m_lastValue );
68 	}
69 	m_bufferLastUpdated = s_periods;
70 }
71 
72 
updateName()73 void MidiController::updateName()
74 {
75 	setName( QString("MIDI ch%1 ctrl%2").
76 			arg( m_midiPort.inputChannel() ).
77 			arg( m_midiPort.inputController() ) );
78 }
79 
80 
81 
82 
processInEvent(const MidiEvent & event,const MidiTime & time,f_cnt_t offset)83 void MidiController::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset )
84 {
85 	unsigned char controllerNum;
86 	switch( event.type() )
87 	{
88 		case MidiControlChange:
89 			controllerNum = event.controllerNumber();
90 
91 			if( m_midiPort.inputController() == controllerNum + 1 &&
92 					( m_midiPort.inputChannel() == event.channel() + 1 ||
93 					  m_midiPort.inputChannel() == 0 ) )
94 			{
95 				unsigned char val = event.controllerValue();
96 				m_previousValue = m_lastValue;
97 				m_lastValue = (float)( val ) / 127.0f;
98 				emit valueChanged();
99 			}
100 			break;
101 
102 		default:
103 			// Don't care - maybe add special cases for pitch and mod later
104 			break;
105 	}
106 }
107 
108 
109 
110 
subscribeReadablePorts(const MidiPort::Map & _map)111 void MidiController::subscribeReadablePorts( const MidiPort::Map & _map )
112 {
113 	for( MidiPort::Map::ConstIterator it = _map.constBegin();
114 						it != _map.constEnd(); ++it )
115 	{
116 		m_midiPort.subscribeReadablePort( it.key(), *it );
117 	}
118 }
119 
120 
121 
122 
saveSettings(QDomDocument & _doc,QDomElement & _this)123 void MidiController::saveSettings( QDomDocument & _doc, QDomElement & _this )
124 {
125 	Controller::saveSettings( _doc, _this );
126 	m_midiPort.saveSettings( _doc, _this );
127 
128 }
129 
130 
131 
132 
loadSettings(const QDomElement & _this)133 void MidiController::loadSettings( const QDomElement & _this )
134 {
135 	Controller::loadSettings( _this );
136 
137 	m_midiPort.loadSettings( _this );
138 
139 	updateName();
140 }
141 
142 
143 
144 
nodeName() const145 QString MidiController::nodeName() const
146 {
147 	return( "Midicontroller" );
148 }
149 
150 
151 
152 
createDialog(QWidget * _parent)153 ControllerDialog * MidiController::createDialog( QWidget * _parent )
154 {
155 	return NULL;
156 }
157 
158 
159 
160 
161