Changeset 990

Show
Ignore:
Timestamp:
03/30/08 15:09:15 (16 years ago)
Author:
jwoithe
Message:

MOTU: make MIDI transmission actually work on the Traveler.
MOTU: parse and store device status stream.
MOTU: minor whitespace cleanups.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp

    r989 r990  
    314314                      unsigned int offset, unsigned int nevents) 
    315315{ 
     316static unsigned int cx = 0; 
    316317    quadlet_t sample; 
    317318    unsigned int j = 0; 
     
    339340    // element is correctly aligned for FFADOs MIDI layer.  The requirement 
    340341    // is that actual MIDI bytes must be aligned to multiples of 8 samples.   
     342 
    341343    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) 
    343346            sample = *(src+2); 
    344347            sample |= 0x01000000; // Flag MIDI byte as being present 
     
    350353    } 
    351354 
     355cx++; 
    352356    return 0;     
    353357} 
     
    367371    arg = src+1; 
    368372    while (j < nevents) { 
     373        unsigned int control_key = *src & ~MOTU_KEY_MASK_MIDI; 
    369374         
    370375        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; 
    378382            } 
    379383        } 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); 
    387403                m_devctrls.status = MOTU_DEVCTRL_VALID; 
    388404            } 
    389405        } 
    390406 
    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; 
    393430                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; 
    394440                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; 
    395450                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; 
    396460                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; 
    397465                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; 
    398470                case MOTU_KEY_MAINOUT_VOL: 
     471                    m_devctrls.main_out_volume = *arg; 
     472                    break; 
    399473                case MOTU_KEY_PHONES_VOL: 
     474                    m_devctrls.phones_volume = *arg; 
     475                    break; 
    400476                case MOTU_KEY_PHONES_DEST: 
     477                    m_devctrls.phones_assign = *arg; 
     478                    break; 
    401479                case MOTU_KEY_INPUT_6dB_BOOST: 
     480                    m_devctrls.input_6dB_boost = *arg; 
     481                    break; 
    402482                case MOTU_KEY_INPUT_REF_LEVEL: 
     483                    m_devctrls.input_ref_level = *arg; 
    403484                    break; 
    404485                case MOTU_KEY_MIDI: 
  • trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.h

    r981 r990  
    6464 
    6565enum 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, 
    6970}; 
    7071 
    7172struct MotuDevControls { 
    72     unsigned int status, lastkey
     73    unsigned int status
    7374    unsigned int input_6dB_boost; 
    7475    unsigned int input_ref_level; 
     
    7778    unsigned char input_gaintrim_index; 
    7879    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; 
    8788    } mixbus[MOTUFW_MAX_MIXBUSES]; 
    8889    unsigned char mixbus_index; 
     
    9091    unsigned char phones_volume; 
    9192    unsigned char phones_assign; 
     93    unsigned char n_mixbuses; 
     94    unsigned char n_channels; 
    9295}; 
    9396 
    9497enum 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 
     113enum 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, 
    106118}; 
    107119 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

    r986 r990  
    6868        , m_event_size( event_size ) 
    6969        , 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
    7183 
    7284unsigned int 
     
    466478    unsigned int i; 
    467479 
    468     // FIXME: ensure the MIDI and control streams are all zeroed until 
    469     // 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
    470482    for (i=0; i<nevents; i++) { 
    471483        memset(data+4+i*m_event_size, 0x00, 6); 
     
    639651    quadlet_t *src = (quadlet_t *)p->getBufferAddress(); 
    640652    src += offset; 
    641  
    642653    unsigned char *target = (unsigned char *)data + p->getPosition(); 
    643654 
     
    647658 
    648659    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) { 
    650681            *(target) = 0x01; 
    651682            *(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        } 
    655688    } 
    656689 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.h

    r873 r990  
    121121    unsigned int m_tx_dbc; 
    122122 
     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 */ 
    123133}; 
    124134