Subversion Repositories svn.mios32

Rev

Rev 2027 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
292 tk 1
// $Id: seq_mixer.c 2659 2019-01-13 14:17:46Z tk $
2
/*
3
 * Mixer Routines
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
18
#include <mios32.h>
19
#include "tasks.h"
20
 
690 tk 21
#include "seq_ui.h"
292 tk 22
#include "seq_mixer.h"
2659 tk 23
#include "seq_midi_in.h"
24
#include "seq_midi_router.h"
1123 tk 25
#include "seq_file.h"
292 tk 26
#include "seq_file_m.h"
27
 
28
 
29
/////////////////////////////////////////////////////////////////////////////
30
// Global variables
31
/////////////////////////////////////////////////////////////////////////////
32
 
33
// should only be directly accessed by SEQ_FILE_M, remaining functions should
34
// use SEQ_MIXER_Get/Set
1535 tk 35
#ifndef AHB_SECTION
36
#define AHB_SECTION
37
#endif
38
u8 AHB_SECTION seq_mixer_value[SEQ_MIXER_NUM_CHANNELS][SEQ_MIXER_NUM_PARAMETERS];
292 tk 39
char seq_mixer_map_name[21];
40
 
2027 tk 41
// flags for CC1..CC4: if cleared, CC will be sent after PC, if set CC will be sent before PC
42
u8 seq_mixer_cc1234_before_pc;
292 tk 43
 
2027 tk 44
 
292 tk 45
/////////////////////////////////////////////////////////////////////////////
401 tk 46
// Local variables
47
/////////////////////////////////////////////////////////////////////////////
48
 
49
static u8 mixer_map;
50
 
51
 
52
/////////////////////////////////////////////////////////////////////////////
292 tk 53
// Initialisation
54
/////////////////////////////////////////////////////////////////////////////
55
s32 SEQ_MIXER_Init(u32 mode)
56
{
401 tk 57
  // select first map
58
  mixer_map = 0;
59
 
2027 tk 60
  // CCs after PC
61
  seq_mixer_cc1234_before_pc = 0;
62
 
292 tk 63
  // clear mixer page
64
  SEQ_MIXER_Clear();
65
 
66
  return 0; // no error
67
}
68
 
69
 
70
/////////////////////////////////////////////////////////////////////////////
71
// Returns the name of the mixer map (20 characters)
72
/////////////////////////////////////////////////////////////////////////////
73
char *SEQ_MIXER_MapNameGet(void)
74
{
75
  return seq_mixer_map_name;
76
}
77
 
78
 
79
/////////////////////////////////////////////////////////////////////////////
401 tk 80
// Get/Set mixer map number
81
/////////////////////////////////////////////////////////////////////////////
82
s32 SEQ_MIXER_NumGet(void)
83
{
84
  return mixer_map;
85
}
86
 
87
s32 SEQ_MIXER_NumSet(u8 map)
88
{
89
  if( map >= SEQ_MIXER_NUM )
90
    return -1; // invalid map number
91
 
92
  mixer_map = map;
93
 
94
  return 0; // no error
95
}
96
 
97
 
98
/////////////////////////////////////////////////////////////////////////////
292 tk 99
// Sets a mixer value
100
/////////////////////////////////////////////////////////////////////////////
101
s32 SEQ_MIXER_Set(u8 chn, seq_mixer_par_t par, u8 value)
102
{
103
  if( chn >= SEQ_MIXER_NUM_CHANNELS )
104
    return -1; // invalid channel number
105
  if( chn >= SEQ_MIXER_NUM_PARAMETERS )
106
    return -2; // invalid parameter number
107
 
108
  seq_mixer_value[chn][par] = value;
109
 
110
  return 0; // no error
111
}
112
 
113
 
114
/////////////////////////////////////////////////////////////////////////////
115
// Returns a mixer value
116
/////////////////////////////////////////////////////////////////////////////
117
s32 SEQ_MIXER_Get(u8 chn, seq_mixer_par_t par)
118
{
119
  if( chn >= SEQ_MIXER_NUM_CHANNELS )
120
    return -1; // invalid channel number
121
  if( chn >= SEQ_MIXER_NUM_PARAMETERS )
122
    return -2; // invalid parameter number
123
 
124
  return seq_mixer_value[chn][par];
125
}
126
 
127
 
128
/////////////////////////////////////////////////////////////////////////////
2659 tk 129
// Sends a CC value, considers Bus target
130
/////////////////////////////////////////////////////////////////////////////
131
static s32 SEQ_MIXER_SendProgramChange(mios32_midi_port_t midi_port, mios32_midi_chn_t midi_chn, u8 pc)
132
{
133
  mios32_midi_package_t midi_package;
134
 
135
  midi_package.type  = 0xc;
136
  midi_package.evnt0 = 0xc0 | midi_chn;
137
  midi_package.evnt1 = pc;
138
  midi_package.evnt2 = 0x00;
139
 
140
  if( (midi_port & 0xf0) == 0xf0 ) { // send to bus?
141
    // forward to router
142
    SEQ_MIDI_ROUTER_Receive(midi_port, midi_package);
143
 
144
    // forward to transposer/arpeggiator/CC parser/etc...
145
    SEQ_MIDI_IN_Receive(midi_port, midi_package);
146
 
147
    return 0; // no error
148
  }
149
 
150
  return MIOS32_MIDI_SendPackage(midi_port, midi_package);
151
}
152
 
153
 
154
/////////////////////////////////////////////////////////////////////////////
155
// Sends a CC value, considers Bus target
156
/////////////////////////////////////////////////////////////////////////////
157
static s32 SEQ_MIXER_SendCC(mios32_midi_port_t midi_port, mios32_midi_chn_t midi_chn, u8 cc, u8 value)
158
{
159
  mios32_midi_package_t midi_package;
160
 
161
  midi_package.type  = 0xb;
162
  midi_package.evnt0 = 0xb0 | midi_chn;
163
  midi_package.evnt1 = cc;
164
  midi_package.evnt2 = value;
165
 
166
  if( (midi_port & 0xf0) == 0xf0 ) { // send to bus?
167
    // forward to router
168
    SEQ_MIDI_ROUTER_Receive(midi_port, midi_package);
169
 
170
    // forward to transposer/arpeggiator/CC parser/etc...
171
    SEQ_MIDI_IN_Receive(midi_port, midi_package);
172
 
173
    return 0; // no error
174
  }
175
 
176
  return MIOS32_MIDI_SendPackage(midi_port, midi_package);
177
}
178
 
179
/////////////////////////////////////////////////////////////////////////////
292 tk 180
// Sends a single mixer value
181
/////////////////////////////////////////////////////////////////////////////
182
s32 SEQ_MIXER_Send(u8 chn, seq_mixer_par_t par)
183
{
184
  mios32_midi_port_t midi_port = SEQ_MIXER_Get(chn, SEQ_MIXER_PAR_PORT);
185
  mios32_midi_chn_t  midi_chn = SEQ_MIXER_Get(chn, SEQ_MIXER_PAR_CHANNEL);
186
 
187
  s32 value;
188
  if( (value=SEQ_MIXER_Get(chn, par)) < 0 )
189
    return 0; // don't return error, as it could be misinterpreded as a MIDI interface issue
190
 
191
  switch( par ) {
192
    case SEQ_MIXER_PAR_PRG:
2659 tk 193
      return value == 0 ? 0 : SEQ_MIXER_SendProgramChange(midi_port, midi_chn, value-1);
292 tk 194
    case SEQ_MIXER_PAR_VOLUME:  
2659 tk 195
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, 7, value-1);
292 tk 196
    case SEQ_MIXER_PAR_PANORAMA:
2659 tk 197
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, 10, value-1);
292 tk 198
    case SEQ_MIXER_PAR_REVERB:  
2659 tk 199
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, 91, value-1);
292 tk 200
    case SEQ_MIXER_PAR_CHORUS:
2659 tk 201
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, 93, value-1);
292 tk 202
    case SEQ_MIXER_PAR_MODWHEEL:
2659 tk 203
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, 1, value-1);
292 tk 204
 
205
    case SEQ_MIXER_PAR_CC1:
2659 tk 206
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, SEQ_MIXER_Get(chn, SEQ_MIXER_PAR_CC1_NUM), value-1);
292 tk 207
    case SEQ_MIXER_PAR_CC2:
2659 tk 208
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, SEQ_MIXER_Get(chn, SEQ_MIXER_PAR_CC2_NUM), value-1);
292 tk 209
    case SEQ_MIXER_PAR_CC3:
2659 tk 210
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, SEQ_MIXER_Get(chn, SEQ_MIXER_PAR_CC3_NUM), value-1);
292 tk 211
    case SEQ_MIXER_PAR_CC4:
2659 tk 212
      return value == 0 ? 0 : SEQ_MIXER_SendCC(midi_port, midi_chn, SEQ_MIXER_Get(chn, SEQ_MIXER_PAR_CC4_NUM), value-1);
292 tk 213
  }
214
 
215
  // not supported
216
  // don't return error, as this could be misinterpreted as a MIDI interface issue
217
  return 0;
218
}
219
 
1454 midilab 220
/////////////////////////////////////////////////////////////////////////////
221
// Sends all mixer values for a specified Channel
222
/////////////////////////////////////////////////////////////////////////////
223
s32 SEQ_MIXER_SendAllByChannel(u8 chn)
224
{
225
  seq_mixer_par_t par;
226
  s32 status = 0;
227
 
1816 tk 228
  MUTEX_MIDIOUT_TAKE;
2027 tk 229
 
230
  // CCs before PC?
231
  for(par=0; par<4; ++par) {
232
    if( seq_mixer_cc1234_before_pc & (1 << par) ) {
233
      status |= SEQ_MIXER_Send(chn, SEQ_MIXER_PAR_CC1 + par);
234
    }
235
  }
236
 
237
  for(par=SEQ_MIXER_PAR_PRG; par<=SEQ_MIXER_PAR_MODWHEEL; ++par)
1454 midilab 238
    status |= SEQ_MIXER_Send(chn, par);
2027 tk 239
 
240
  // CCs after PC?
241
  for(par=0; par<4; ++par) {
242
    if( !(seq_mixer_cc1234_before_pc & (1 << par)) ) {
243
      status |= SEQ_MIXER_Send(chn, SEQ_MIXER_PAR_CC1 + par);
244
    }
245
  }
246
 
1816 tk 247
  MUTEX_MIDIOUT_GIVE;
1454 midilab 248
 
249
  return status;
250
}
292 tk 251
 
252
/////////////////////////////////////////////////////////////////////////////
253
// Sends all mixer values
254
/////////////////////////////////////////////////////////////////////////////
255
s32 SEQ_MIXER_SendAll(void)
256
{
257
  u8 chn;
258
  s32 status = 0;
259
 
1816 tk 260
  MUTEX_MIDIOUT_TAKE;
292 tk 261
  for(chn=0; chn<SEQ_MIXER_NUM_CHANNELS; ++chn)
2027 tk 262
    SEQ_MIXER_SendAllByChannel(chn);
1816 tk 263
  MUTEX_MIDIOUT_GIVE;
292 tk 264
 
265
  return status;
266
}
267
 
268
 
269
/////////////////////////////////////////////////////////////////////////////
270
// Clears a mixer page
271
/////////////////////////////////////////////////////////////////////////////
272
s32 SEQ_MIXER_Clear(void)
273
{
274
  // init name
275
  int i;
276
  for(i=0; i<20; ++i)
277
    seq_mixer_map_name[i] = ' ';
278
  seq_mixer_map_name[i] = 0;
279
 
280
  u8 chn, par;
281
  // init mixer values
282
  for(chn=0; chn<SEQ_MIXER_NUM_CHANNELS; ++chn) {
283
    for(par=0; par<SEQ_MIXER_NUM_PARAMETERS; ++par)
284
      seq_mixer_value[chn][par] = 0;
285
 
286
    seq_mixer_value[chn][SEQ_MIXER_PAR_CHANNEL] = chn & 0xf;
287
    seq_mixer_value[chn][SEQ_MIXER_PAR_CC1_NUM] = 16;
288
    seq_mixer_value[chn][SEQ_MIXER_PAR_CC2_NUM] = 17;
289
    seq_mixer_value[chn][SEQ_MIXER_PAR_CC3_NUM] = 18;
290
    seq_mixer_value[chn][SEQ_MIXER_PAR_CC4_NUM] = 19;
291
  }
292
 
293
  return 0; // no error
294
}
295
 
296
 
297
/////////////////////////////////////////////////////////////////////////////
298
// Loads a mixer map
299
/////////////////////////////////////////////////////////////////////////////
300
s32 SEQ_MIXER_Load(u8 map)
301
{
299 tk 302
  s32 status;
303
 
401 tk 304
  if( map >= SEQ_MIXER_NUM )
305
    return -1; // invalid map number
306
 
292 tk 307
  MUTEX_SDCARD_TAKE;
299 tk 308
  if( (status=SEQ_FILE_M_MapRead(map)) < 0 )
309
    SEQ_UI_SDCardErrMsg(2000, status);
292 tk 310
  MUTEX_SDCARD_GIVE;
299 tk 311
 
401 tk 312
  // change to new map
313
  mixer_map = map;
314
 
299 tk 315
  return status;
292 tk 316
}
317
 
318
 
319
/////////////////////////////////////////////////////////////////////////////
320
// Stores a mixer map
321
/////////////////////////////////////////////////////////////////////////////
322
s32 SEQ_MIXER_Save(u8 map)
323
{
299 tk 324
  s32 status;
325
 
401 tk 326
  if( map >= SEQ_MIXER_NUM )
327
    return -1; // invalid map number
328
 
292 tk 329
  MUTEX_SDCARD_TAKE;
1123 tk 330
  if( (status=SEQ_FILE_M_MapWrite(seq_file_session_name, map, 1)) < 0 )
299 tk 331
    SEQ_UI_SDCardErrMsg(2000, status);
292 tk 332
  MUTEX_SDCARD_GIVE;
299 tk 333
 
401 tk 334
  // change to new map
335
  mixer_map = map;
336
 
299 tk 337
  return status;
292 tk 338
}