Changeset 1869

Show
Ignore:
Timestamp:
07/18/10 07:42:58 (2 years ago)
Author:
jwoithe
Message:

RME: more receive streaming changes. The resulting code has enabled the first successful audio capture from an RME firewire interface to Linux (test was done using FF400).
RME: work towards getting playback working (no success yet - just silence).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/libstreaming/rme/RmeReceiveStreamProcessor.cpp

    r1865 r1869  
    115115//fprintf(stderr, "recv len=%d\n", length); 
    116116 
    117     if (length > 8) { 
     117    if (length > 0) { 
    118118        // The iso data blocks from the RMEs comprise 24-bit audio 
    119119        // data encoded in 32-bit integers.  The LSB of the 32-bit integers 
     
    238238    unsigned int j=0; 
    239239 
    240     // Use char here since a port's source address won't necessarily be 
    241     // aligned; use of an unaligned quadlet_t may cause issues on certain 
    242     // architectures.  Besides, the source (data coming directly from the 
    243     // RME) isn't structured in quadlets anyway; it consists 24-bit integers 
    244     // within 32-bit quadlets with the LSB being a housekeeping byte. 
    245  
    246     unsigned char *src_data; 
    247     src_data = (unsigned char *)data + p->getPosition(); 
     240    // For RME interfaces the audio data is contained in the most significant 
     241    // 24 bits of a 32-bit field.  Thus it makes sense to treat the source 
     242    // data as 32 bit and simply mask/shift as necessary to isolate the 
     243    // audio data. 
     244    quadlet_t *src_data; 
     245    src_data = data + p->getPosition()/4; 
    248246 
    249247    switch(m_StreamProcessorManager.getAudioDataType()) { 
     
    262260 
    263261                for(j = 0; j < nevents; j += 1) { // Decode nsamples 
    264                     *buffer = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2)
    265                     // Sign-extend highest bit of 24-bit int. 
    266                     // This isn't strictly needed since E_Int24 is a 24-bit, 
    267                     // but doing so shouldn't break anything and makes the data 
    268                     // easier to deal with during debugging. 
    269                     if (*src_data & 0x80
     262                    *buffer = (*src_data >> 8) & 0x00ffffff
     263                    // Sign-extend highest bit of 24-bit int.  This isn't 
     264                    // strictly needed since E_Int24 is a 24-bit, but doing 
     265                    // so shouldn't break anything and makes the data easier 
     266                    // to deal with during debugging. 
     267                    if (*src_data & 0x80000000
    270268                        *buffer |= 0xff000000; 
    271269 
    272270                    buffer++; 
    273                     src_data+=m_event_size
     271                    src_data+=m_event_size/4
    274272                } 
    275273            } 
     
    285283 
    286284                for(j = 0; j < nevents; j += 1) { // decode max nsamples 
    287  
    288                     signed int v = (*src_data<<16)+(*(src_data+1)<<8)+*(src_data+2); 
     285                    signed int v = (*src_data >> 8) & 0x00ffffff; 
    289286                    /* Sign-extend highest bit of incoming 24-bit integer */ 
    290                     if (*src_data & 0x80
     287                    if (*src_data & 0x80000000
    291288                      v |= 0xff000000; 
    292289                    *buffer = v * multiplier; 
    293290                    buffer++; 
    294                     src_data+=m_event_size
     291                    src_data+=m_event_size/4
    295292                } 
    296293            } 
  • trunk/libffado/src/libstreaming/rme/RmeTransmitStreamProcessor.cpp

    r1868 r1869  
    107107{ 
    108108    unsigned int cycle = CYCLE_TIMER_GET_CYCLES(pkt_ctr); 
     109    signed n_events = getNominalFramesPerPacket(); 
    109110 
    110111    // Called once per packet.  Need to work out whether data should be sent 
     
    116117    // they will contain data. 
    117118    *sy = 0x00; 
    118     *length = 0
     119    *length = n_events*m_event_size
    119120 
    120121    signed int fc; 
     
    273274    unsigned char *data, unsigned int *length) 
    274275{ 
    275     quadlet_t *quadlet = (quadlet_t *)data; 
    276     quadlet += 2; // skip the header 
    277276    // Size of a single data frame in quadlets 
    278277//    unsigned dbs = m_event_size / 4; 
     
    283282    signed n_events = getNominalFramesPerPacket(); 
    284283 
    285     if (m_data_buffer->readFrames(n_events, (char *)(data + 8))) { 
     284    if (m_data_buffer->readFrames(n_events, (char *)(data))) { 
    286285//        float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame(); 
    287286 
     
    291290//        } 
    292291        // FIXME: temporary 
    293         if (*length > 0) { 
    294             memset(data, *length, 0); 
    295         } 
     292//        if (*length > 0) { 
     293//            memset(data, *length, 0); 
     294//        } 
     295// 
     296// 1 kHz tone into ch7 (phones L) for testing 
     297
     298float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame(); 
     299  signed int i, int_tpf = lrintf(ticks_per_frame); 
     300  quadlet_t *sample = (quadlet_t *)data + 6; 
     301  for (i=0; i<n_events; i++, sample+=m_event_size/4) { 
     302    static signed int a_cx = 0; 
     303    signed int val = lrintf(0x7fffff*sin((1000.0*2.0*M_PI/24576000.0)*a_cx)); 
     304    *sample = val << 8; 
     305    if ((a_cx+=int_tpf) >= 24576000) { 
     306      a_cx -= 24576000; 
     307    } 
     308  } 
     309
     310 
    296311        return eCRV_OK; 
    297312    } 
    298313    else 
    299314    { 
    300         // FIMXE: debugOutput() for initial testing only 
     315        // FIXME: debugOutput() for initial testing only 
    301316        debugOutput(DEBUG_LEVEL_VERBOSE, "readFrames() failure\n"); 
    302317        return eCRV_XRun; 
     
    409424     * the length will be overridden by fillNoDataPacketHeader(). 
    410425     */ 
    411     *length = n_events*m_event_size + 8
     426    *length = n_events*m_event_size
    412427 
    413428    uint64_t presentation_time; 
     
    469484{ 
    470485    // Simply set all audio data to zero since that's what's meant by 
    471     // a "silent" packet.  Note that m_event_size is in bytes. 
    472  
    473     quadlet_t *quadlet = (quadlet_t *)data; 
    474     quadlet += 2; // skip the header 
    475     // Size of a single data frame in quadlets 
    476     unsigned dbs = m_event_size / 4; 
     486    // a "silent" packet. 
     487    memset(data, 0, *length); 
     488 
     489    return eCRV_OK; 
     490
     491 
     492unsigned int RmeTransmitStreamProcessor::fillDataPacketHeader ( 
     493    quadlet_t *data, unsigned int* length, 
     494    uint32_t ts ) 
     495
     496//    quadlet_t *quadlet = (quadlet_t *)data; 
     497    // Size of a single data frame in quadlets. 
     498//    unsigned dbs = m_event_size / 4; 
    477499 
    478500    // The number of events per packet expected by the RME is solely 
     
    481503    signed n_events = getNominalFramesPerPacket(); 
    482504 
    483     memset(quadlet, 0, n_events*m_event_size); 
    484 //    float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame(); 
    485  
    486     // Set up each frames's SPH. 
    487     for (int i=0; i < n_events; i++, quadlet += dbs) { 
    488 //        int64_t ts_frame = addTicks(m_last_timestamp, (unsigned int)lrintf(i * ticks_per_frame)); 
    489 // FIXME: 
    490 //        *quadlet = CondSwapToBus32(fullTicksToSph(ts_frame)); 
    491     } 
    492     return eCRV_OK; 
    493 } 
    494  
    495 unsigned int RmeTransmitStreamProcessor::fillDataPacketHeader ( 
    496     quadlet_t *data, unsigned int* length, 
    497     uint32_t ts ) 
    498 { 
    499 //    quadlet_t *quadlet = (quadlet_t *)data; 
    500     // Size of a single data frame in quadlets. 
    501 //    unsigned dbs = m_event_size / 4; 
    502  
    503     // The number of events per packet expected by the RME is solely 
    504     // dependent on the current sample rate.  An 'event' is one sample from 
    505     // all channels plus possibly other midi and control data. 
    506     signed n_events = getNominalFramesPerPacket(); 
    507  
    508     // construct the packet CIP-like header.  Even if this is a data-less 
    509     // packet the dbs field is still set as if there were data blocks 
    510     // present.  For data-less packets the dbc is the same as the previously 
    511     // transmitted block. 
    512 //    *quadlet = CondSwapToBus32(0x00000400 | ((m_Parent.get1394Service().getLocalNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16)); 
    513 //    quadlet++; 
    514 //    *quadlet = CondSwapToBus32(0x8222ffff); 
    515 //    quadlet++; 
    516505    return n_events; 
    517506} 
     
    520509    quadlet_t *data, unsigned int* length ) 
    521510{ 
    522 //    quadlet_t *quadlet = (quadlet_t *)data; 
    523     // Size of a single data frame in quadlets. 
    524 //    unsigned dbs = m_event_size / 4; 
    525     // construct the packet CIP-like header.  Even if this is a data-less 
    526     // packet the dbs field is still set as if there were data blocks 
    527     // present.  For data-less packets the dbc is the same as the previously 
    528     // transmitted block. 
    529 //    *quadlet = CondSwapToBus32(0x00000400 | ((m_Parent.get1394Service().getLocalNodeId()&0x3f)<<24) | m_tx_dbc | (dbs<<16)); 
    530 //    quadlet++; 
    531 //    *quadlet = CondSwapToBus32(0x8222ffff); 
    532 //    quadlet++; 
    533     *length = 8; 
     511    *length = 0; 
    534512    return 0; 
    535513} 
     
    547525                       unsigned int nevents, unsigned int offset) { 
    548526    bool no_problem=true; 
    549     unsigned int i; 
    550  
    551     // Start with MIDI and control streams all zeroed.  Due to the sparce nature 
    552     // of these streams it is best to simply fill them in on an as-needs basis. 
    553     for (i=0; i<nevents; i++) { 
    554         memset(data+4+i*m_event_size, 0x00, 6); 
    555     } 
    556527 
    557528    for ( PortVectorIterator it = m_Ports.begin(); 
     
    640611    unsigned int j=0; 
    641612 
    642     // Use char here since the target address won't necessarily be 
    643     // aligned; use of an unaligned quadlet_t may cause issues on certain 
    644     // architectures.  Besides, the target (data going directly to the RME) 
    645     // isn't structured in quadlets anyway; it mainly consists of packed 
    646     // 24-bit integers. 
    647     unsigned char *target; 
    648     target = (unsigned char *)data + p->getPosition(); 
     613    quadlet_t *target; 
     614    target = data + p->getPosition()/4; 
    649615 
    650616    switch(m_StreamProcessorManager.getAudioDataType()) { 
     
    663629 
    664630                for(j = 0; j < nevents; j += 1) { // Decode nsamples 
    665                     *target = (*buffer >> 16) & 0xff; 
    666                     *(target+1) = (*buffer >> 8) & 0xff; 
    667                     *(target+2) = (*buffer) & 0xff; 
    668  
     631                    *target = (*buffer & 0x00ffffff) << 8; 
    669632                    buffer++; 
    670                     target+=m_event_size
     633                    target+=m_event_size/4
    671634                } 
    672635            } 
     
    688651#endif 
    689652                    unsigned int v = lrintf(in * multiplier); 
    690                     *target = (v >> 16) & 0xff; 
    691                     *(target+1) = (v >> 8) & 0xff; 
    692                     *(target+2) = v & 0xff; 
    693  
     653                    *target = (v << 8); 
    694654                    buffer++; 
    695                     target+=m_event_size
     655                    target+=m_event_size/4
    696656                } 
    697657            } 
     
    705665                       unsigned int offset, unsigned int nevents) { 
    706666    unsigned int j=0; 
    707     unsigned char *target = (unsigned char *)data + p->getPosition()
     667    quadlet_t *target = data + p->getPosition()/4
    708668 
    709669    switch (m_StreamProcessorManager.getAudioDataType()) { 
     
    712672        case StreamProcessorManager::eADT_Float: 
    713673        for (j = 0; j < nevents; j++) { 
    714             *target = *(target+1) = *(target+2) = 0; 
    715             target += m_event_size
     674            *target = 0; 
     675            target += m_event_size/4
    716676        } 
    717677        break; 
  • trunk/libffado/src/rme/rme_avdevice.cpp

    r1868 r1869  
    3737#include "debugmodule/debugmodule.h" 
    3838 
     39#include "libstreaming/rme/RmePort.h" 
     40 
    3941#include "devicemanager.h" 
    4042 
     
    682684        debugWarning("Could not retrieve id parameter, defaulting to 'dev?'\n"); 
    683685    } 
     686    addDirPorts(Streaming::Port::E_Capture); 
    684687 
    685688    /* Now set up the transmit stream processor */ 
     
    700703    // Other things to be done: 
    701704    //  * add ports to transmit stream processor 
     705    addDirPorts(Streaming::Port::E_Playback); 
    702706 
    703707    return true; 
     
    763767} 
    764768 
     769bool  
     770Device::addPort(Streaming::StreamProcessor *s_processor, 
     771    char *name, enum Streaming::Port::E_Direction direction, 
     772    int position, int size) { 
     773 
     774    Streaming::Port *p; 
     775    p = new Streaming::RmeAudioPort(*s_processor, name, direction, position, size); 
     776    if (p == NULL) { 
     777        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",name); 
     778    } 
     779    return true; 
     780} 
     781 
     782bool  
     783Device::addDirPorts(enum Streaming::Port::E_Direction direction) { 
     784 
     785    const char *mode_str = direction==Streaming::Port::E_Capture?"cap":"pbk"; 
     786    Streaming::StreamProcessor *s_processor; 
     787    std::string id; 
     788    char name[128]; 
     789 
     790    if (direction == Streaming::Port::E_Capture) { 
     791        s_processor = m_receiveProcessor; 
     792    } else { 
     793        s_processor = m_transmitProcessor; 
     794    } 
     795 
     796    id = std::string("dev?"); 
     797    if (!getOption("id", id)) { 
     798        debugWarning("Could not retrieve id parameter, defaulting to 'dev?'\n"); 
     799    } 
     800 
     801    // Just add a few ports for initial testing 
     802    snprintf(name, sizeof(name), "%s_%s_%s", id.c_str(), mode_str, "port_0"); 
     803    addPort(s_processor, name, direction, 0, 0); 
     804    snprintf(name, sizeof(name), "%s_%s_%s", id.c_str(), mode_str, "port_1"); 
     805    addPort(s_processor, name, direction, 4, 0); 
     806    snprintf(name, sizeof(name), "%s_%s_%s", id.c_str(), mode_str, "port_6"); 
     807    addPort(s_processor, name, direction, 24, 0); 
     808    snprintf(name, sizeof(name), "%s_%s_%s", id.c_str(), mode_str, "port_7"); 
     809    addPort(s_processor, name, direction, 28, 0); 
     810 
     811    return true; 
     812} 
     813 
    765814unsigned int  
    766815Device::readRegister(fb_nodeaddr_t reg) { 
  • trunk/libffado/src/rme/rme_avdevice.h

    r1857 r1869  
    9292    signed int getNumChannels(void) { return num_channels; }; 
    9393    signed int getFramesPerPacket(void); 
     94 
     95    bool addPort(Streaming::StreamProcessor *s_processor, 
     96             char *name, enum Streaming::Port::E_Direction direction, 
     97             int position, int size); 
     98    bool addDirPorts(enum Streaming::Port::E_Direction direction); 
    9499 
    95100    unsigned int readRegister(fb_nodeaddr_t reg);