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