Changeset 990
- Timestamp:
- 03/30/08 15:09:15 (16 years ago)
- Files:
-
- trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp (modified) (4 diffs)
- trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.h (modified) (3 diffs)
- trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp (modified) (4 diffs)
- trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp
r989 r990 314 314 unsigned int offset, unsigned int nevents) 315 315 { 316 static unsigned int cx = 0; 316 317 quadlet_t sample; 317 318 unsigned int j = 0; … … 339 340 // element is correctly aligned for FFADOs MIDI layer. The requirement 340 341 // is that actual MIDI bytes must be aligned to multiples of 8 samples. 342 341 343 while (j < nevents) { 342 if ((*src & 0x01) == 0x01) { // A MIDI byte is in *(src+2) 344 if ((*src & MOTU_KEY_MASK_MIDI) == MOTU_KEY_MASK_MIDI) { 345 // A MIDI byte is in *(src+2) 343 346 sample = *(src+2); 344 347 sample |= 0x01000000; // Flag MIDI byte as being present … … 350 353 } 351 354 355 cx++; 352 356 return 0; 353 357 } … … 367 371 arg = src+1; 368 372 while (j < nevents) { 373 unsigned int control_key = *src & ~MOTU_KEY_MASK_MIDI; 369 374 370 375 if (m_devctrls.status == MOTU_DEVCTRL_INVALID) { 371 // Start acquiring on reception of a key which we know occurs 372 // only once per cycle. The only potential problem with this is if 373 // this key can interrupt a sequence of other keys. Time will tell 374 // whether the assumption that it doesn't is valid. 375 if (*src == MOTU_KEY_MAINOUT_VOL) { 376 debugOutput(DEBUG_LEVEL_VERBOSE, "acquiring device control status events\n"); 377 m_devctrls.status = MOTU_DEVCTRL_ACQUIRING; 376 // Start syncing on reception of the sequence sync key which indicates 377 // mix bus 1 values are pending. Acquisition will start when we see the 378 // first channel gain key after this. 379 if (control_key==MOTU_KEY_SEQ_SYNC && *arg==MOTU_KEY_SEQ_SYNC_MIXBUS1) { 380 debugOutput(DEBUG_LEVEL_VERBOSE, "syncing device control status stream\n"); 381 m_devctrls.status = MOTU_DEVCTRL_SYNCING; 378 382 } 379 383 } else 380 if (m_devctrls.status == MOTU_DEVCTRL_ACQUIRING) { 381 // If our "once per cycle" key occurs in the acquiring state we 382 // know we've been right through the control event cycle, making 383 // our picture of the device status complete. See note above 384 // for the caveats with this logic. 385 if (*src == MOTU_KEY_MAINOUT_VOL) { 386 debugOutput(DEBUG_LEVEL_VERBOSE, "device control status collection valid\n"); 384 if (m_devctrls.status == MOTU_DEVCTRL_SYNCING) { 385 // Start acquiring when we see a channel gain key for mixbus 1. 386 if (control_key == MOTU_KEY_SEQ_SYNC) { 387 // Keep mixbus index updated since we don't execute the main parser until 388 // we move to the initialising state. Since we don't dereference this until 389 // we know it's equal to 0 there's no need for bounds checking here. 390 m_devctrls.mixbus_index = *arg; 391 } else 392 if (control_key==MOTU_KEY_CHANNEL_GAIN && m_devctrls.mixbus_index==0) { 393 debugOutput(DEBUG_LEVEL_VERBOSE, "initialising device control status\n"); 394 m_devctrls.status = MOTU_DEVCTRL_INIT; 395 } 396 } else 397 if (m_devctrls.status == MOTU_DEVCTRL_INIT) { 398 // Consider ourselves fully initialised when a control sequence sync key 399 // arrives which takes things back to mixbus 1. 400 if (control_key==MOTU_KEY_SEQ_SYNC && *arg==MOTU_KEY_SEQ_SYNC_MIXBUS1 && m_devctrls.mixbus_index>0) { 401 debugOutput(DEBUG_LEVEL_VERBOSE, "device control status valid: n_mixbuses=%d, n_channels=%d\n", 402 m_devctrls.n_mixbuses, m_devctrls.n_channels); 387 403 m_devctrls.status = MOTU_DEVCTRL_VALID; 388 404 } 389 405 } 390 406 391 if (m_devctrls.status != MOTU_DEVCTRL_INVALID) { 392 switch (*src) { 407 if (m_devctrls.status==MOTU_DEVCTRL_INIT || m_devctrls.status==MOTU_DEVCTRL_VALID) { 408 unsigned int i; 409 switch (control_key) { 410 case MOTU_KEY_SEQ_SYNC: 411 if (m_devctrls.mixbus_index < MOTUFW_MAX_MIXBUSES) { 412 if (m_devctrls.n_channels==0 && m_devctrls.mixbus[m_devctrls.mixbus_index].channel_gain_index!=0) { 413 m_devctrls.n_channels = m_devctrls.mixbus[m_devctrls.mixbus_index].channel_gain_index; 414 } 415 } 416 /* Mix bus to configure next is in bits 5-7 of the argument */ 417 m_devctrls.mixbus_index = (*arg >> 5); 418 if (m_devctrls.mixbus_index >= MOTUFW_MAX_MIXBUSES) { 419 debugWarning("MOTU cuemix value parser error: mix bus index %d exceeded maximum %d\n", 420 m_devctrls.mixbus_index, MOTUFW_MAX_MIXBUSES); 421 } else { 422 if (m_devctrls.n_mixbuses < m_devctrls.mixbus_index+1) { 423 m_devctrls.n_mixbuses = m_devctrls.mixbus_index+1; 424 } 425 m_devctrls.mixbus[m_devctrls.mixbus_index].channel_gain_index = 426 m_devctrls.mixbus[m_devctrls.mixbus_index].channel_pan_index = 427 m_devctrls.mixbus[m_devctrls.mixbus_index].channel_control_index = 0; 428 } 429 break; 393 430 case MOTU_KEY_CHANNEL_GAIN: 431 i = m_devctrls.mixbus[m_devctrls.mixbus_index].channel_gain_index++; 432 if (m_devctrls.mixbus_index<MOTUFW_MAX_MIXBUSES && i<MOTUFW_MAX_MIXBUS_CHANNELS) { 433 m_devctrls.mixbus[m_devctrls.mixbus_index].channel_gain[i] = *arg; 434 } 435 if (i >= MOTUFW_MAX_MIXBUS_CHANNELS) { 436 debugWarning("MOTU cuemix value parser error: channel gain index %d exceeded maximum %d\n", 437 i, MOTUFW_MAX_MIXBUS_CHANNELS); 438 } 439 break; 394 440 case MOTU_KEY_CHANNEL_PAN: 441 i = m_devctrls.mixbus[m_devctrls.mixbus_index].channel_pan_index++; 442 if (m_devctrls.mixbus_index<MOTUFW_MAX_MIXBUSES && i<MOTUFW_MAX_MIXBUS_CHANNELS) { 443 m_devctrls.mixbus[m_devctrls.mixbus_index].channel_pan[i] = *arg; 444 } 445 if (i >= MOTUFW_MAX_MIXBUS_CHANNELS) { 446 debugWarning("MOTU cuemix value parser error: channel pan index %d exceeded maximum %d\n", 447 i, MOTUFW_MAX_MIXBUS_CHANNELS); 448 } 449 break; 395 450 case MOTU_KEY_CHANNEL_CTRL: 451 i = m_devctrls.mixbus[m_devctrls.mixbus_index].channel_control_index++; 452 if (m_devctrls.mixbus_index<MOTUFW_MAX_MIXBUSES && i<MOTUFW_MAX_MIXBUS_CHANNELS) { 453 m_devctrls.mixbus[m_devctrls.mixbus_index].channel_control[i] = *arg; 454 } 455 if (i >= MOTUFW_MAX_MIXBUS_CHANNELS) { 456 debugWarning("MOTU cuemix value parser error: channel control index %d exceeded maximum %d\n", 457 i, MOTUFW_MAX_MIXBUS_CHANNELS); 458 } 459 break; 396 460 case MOTU_KEY_MIXBUS_GAIN: 461 if (m_devctrls.mixbus_index < MOTUFW_MAX_MIXBUSES) { 462 m_devctrls.mixbus[m_devctrls.mixbus_index].bus_gain = *arg; 463 } 464 break; 397 465 case MOTU_KEY_MIXBUS_DEST: 466 if (m_devctrls.mixbus_index < MOTUFW_MAX_MIXBUSES) { 467 m_devctrls.mixbus[m_devctrls.mixbus_index].bus_dest = *arg; 468 } 469 break; 398 470 case MOTU_KEY_MAINOUT_VOL: 471 m_devctrls.main_out_volume = *arg; 472 break; 399 473 case MOTU_KEY_PHONES_VOL: 474 m_devctrls.phones_volume = *arg; 475 break; 400 476 case MOTU_KEY_PHONES_DEST: 477 m_devctrls.phones_assign = *arg; 478 break; 401 479 case MOTU_KEY_INPUT_6dB_BOOST: 480 m_devctrls.input_6dB_boost = *arg; 481 break; 402 482 case MOTU_KEY_INPUT_REF_LEVEL: 483 m_devctrls.input_ref_level = *arg; 403 484 break; 404 485 case MOTU_KEY_MIDI: trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.h
r981 r990 64 64 65 65 enum EMotuDevCtrlStatus { 66 MOTU_DEVCTRL_INVALID = 0x00, 67 MOTU_DEVCTRL_ACQUIRING = 0x01, 68 MOTU_DEVCTRL_VALID = 0x02, 66 MOTU_DEVCTRL_INVALID = 0x00, 67 MOTU_DEVCTRL_SYNCING = 0x01, 68 MOTU_DEVCTRL_INIT = 0x02, 69 MOTU_DEVCTRL_VALID = 0x03, 69 70 }; 70 71 71 72 struct MotuDevControls { 72 unsigned int status , lastkey;73 unsigned int status; 73 74 unsigned int input_6dB_boost; 74 75 unsigned int input_ref_level; … … 77 78 unsigned char input_gaintrim_index; 78 79 struct MixBus { 79 unsigned char channel_gain[MOTUFW_MAX_MIXBUS_CHANNELS];80 unsigned char channel_gain_index;81 unsigned char channel_pan[MOTUFW_MAX_MIXBUS_CHANNELS];82 unsigned char channel_pan_index;83 unsigned char channel_control[MOTUFW_MAX_MIXBUS_CHANNELS];84 unsigned char channel_control_index;85 unsigned char bus_gain;86 unsigned char bus_dest;80 unsigned char channel_gain[MOTUFW_MAX_MIXBUS_CHANNELS]; 81 unsigned char channel_gain_index; 82 unsigned char channel_pan[MOTUFW_MAX_MIXBUS_CHANNELS]; 83 unsigned char channel_pan_index; 84 unsigned char channel_control[MOTUFW_MAX_MIXBUS_CHANNELS]; 85 unsigned char channel_control_index; 86 unsigned char bus_gain; 87 unsigned char bus_dest; 87 88 } mixbus[MOTUFW_MAX_MIXBUSES]; 88 89 unsigned char mixbus_index; … … 90 91 unsigned char phones_volume; 91 92 unsigned char phones_assign; 93 unsigned char n_mixbuses; 94 unsigned char n_channels; 92 95 }; 93 96 94 97 enum EMotuCtrlKeys { 95 MOTU_KEY_MIDI = 0x01, 96 MOTU_KEY_CHANNEL_GAIN = 0x14, 97 MOTU_KEY_CHANNEL_PAN = 0x1c, 98 MOTU_KEY_CHANNEL_CTRL = 0x24, 99 MOTU_KEY_MIXBUS_GAIN = 0x2c, 100 MOTU_KEY_MIXBUS_DEST = 0x34, 101 MOTU_KEY_MAINOUT_VOL = 0x3c, 102 MOTU_KEY_PHONES_VOL = 0x44, 103 MOTU_KEY_PHONES_DEST = 0x4c, 104 MOTU_KEY_INPUT_6dB_BOOST = 0x6c, 105 MOTU_KEY_INPUT_REF_LEVEL = 0x74, 98 MOTU_KEY_MIDI = 0x01, 99 MOTU_KEY_SEQ_SYNC = 0x0c, 100 MOTU_KEY_CHANNEL_GAIN = 0x14, 101 MOTU_KEY_CHANNEL_PAN = 0x1c, 102 MOTU_KEY_CHANNEL_CTRL = 0x24, 103 MOTU_KEY_MIXBUS_GAIN = 0x2c, 104 MOTU_KEY_MIXBUS_DEST = 0x34, 105 MOTU_KEY_MAINOUT_VOL = 0x3c, 106 MOTU_KEY_PHONES_VOL = 0x44, 107 MOTU_KEY_PHONES_DEST = 0x4c, 108 MOTU_KEY_INPUT_6dB_BOOST = 0x6c, 109 MOTU_KEY_INPUT_REF_LEVEL = 0x74, 110 MOTU_KEY_MASK_MIDI = 0x01, 111 }; 112 113 enum EMotuSeqSyncMixbuses { 114 MOTU_KEY_SEQ_SYNC_MIXBUS1 = 0x00, 115 MOTU_KEY_SEQ_SYNC_MIXBUS2 = 0x20, 116 MOTU_KEY_SEQ_SYNC_MIXBUS3 = 0x40, 117 MOTU_KEY_SEQ_SYNC_MIXBUS4 = 0x60, 106 118 }; 107 119 trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp
r986 r990 68 68 , m_event_size( event_size ) 69 69 , m_tx_dbc( 0 ) 70 {} 70 , mb_head( 0 ) 71 , mb_tail( 0 ) 72 , midi_lock( 0 ) 73 { 74 int srate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 75 /* Work out how many audio samples should be left between MIDI data bytes in order 76 * to stay under the MIDI hardware baud rate of 31250. MIDI data is transmitted 77 * using 10 bits per byte (including the start/stop bit) so this gives us 3125 bytes 78 * per second. If we send to the MOTU at a faster rate than this, some MIDI bytes 79 * will be dropped or corrupted in interesting ways. 80 */ 81 midi_tx_period = lrintf(ceil((float)srate / 3125)); 82 } 71 83 72 84 unsigned int … … 466 478 unsigned int i; 467 479 468 // FIXME: ensure the MIDI and control streams are all zeroed until469 // such time as they are fully implemented.480 // Start with MIDI and control streams all zeroed. Due to the sparce nature 481 // of these streams it is best to simply fill them in on an as-needs basis. 470 482 for (i=0; i<nevents; i++) { 471 483 memset(data+4+i*m_event_size, 0x00, 6); … … 639 651 quadlet_t *src = (quadlet_t *)p->getBufferAddress(); 640 652 src += offset; 641 642 653 unsigned char *target = (unsigned char *)data + p->getPosition(); 643 654 … … 647 658 648 659 for (j=0; j<nevents; j++, src++, target+=m_event_size) { 649 if (*src & 0xff000000) { /* A MIDI byte is ready to send */ 660 if (midi_lock) 661 midi_lock--; 662 663 if (*src & 0xff000000) { /* A MIDI byte is ready to send - buffer it */ 664 midibuffer[mb_head++] = *src; 665 mb_head &= MIDIBUFFER_SIZE-1; 666 if (mb_head == mb_tail) { 667 /* Buffer overflow - dump oldest byte */ 668 /* FIXME: ideally this would dump an entire MIDI message, but this is only 669 * feasible if it's possible to determine the message size easily. 670 */ 671 mb_tail = (mb_tail+1) & (MIDIBUFFER_SIZE-1); 672 debugWarning("MOTU MIDI buffer overflow\n"); 673 } 674 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Buffered MIDI byte %d\n", *src & 0xff); 675 } 676 677 /* Send the MIDI byte at the tail of the buffer if enough time has elapsed 678 * since the last MIDI byte was sent. 679 */ 680 if (mb_head!=mb_tail && !midi_lock) { 650 681 *(target) = 0x01; 651 682 *(target+1) = 0x00; 652 *(target+2) = (*src & 0xff); 653 } else 654 memset(target, 0, 3); 683 *(target+2) = midibuffer[mb_tail] & 0xff; 684 debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Sent MIDI byte %d (j=%d)\n", midibuffer[mb_tail], j); 685 mb_tail = (mb_tail+1) & (MIDIBUFFER_SIZE-1); 686 midi_lock = midi_tx_period; 687 } 655 688 } 656 689 trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.h
r873 r990 121 121 unsigned int m_tx_dbc; 122 122 123 // A simple circular buffer for outgoing MIDI data to allow 124 // a rate control to be implemented on the data to suit the MOTU 125 // devices. Note that this buffer's size is forced to be a power 126 // of 2 to allow for buffer manipulation optimisations. 127 #define MIDIBUFFER_SIZE_EXP 10 128 #define MIDIBUFFER_SIZE (1<<MIDIBUFFER_SIZE_EXP) 129 unsigned int midibuffer[MIDIBUFFER_SIZE]; 130 unsigned int mb_head, mb_tail; 131 unsigned int midi_lock; 132 unsigned int midi_tx_period; /* Measured in audio clock periods */ 123 133 }; 124 134