Show
Ignore:
Timestamp:
11/28/07 12:02:08 (13 years ago)
Author:
ppalmers
Message:

- Adapt the ffado external API (upgrade to v3)

NEEDS NEW JACK BACKEND

- simplify FFADODevice constructor even more
- implement first framework support for supporting multiple adapters.

currently all firewire adapters are scanned for supported devices unless specified otherwise
however attaching devices to separate adapters is not supported. using multiple adapters at
that are connected together might work.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/ffado.cpp

    r554 r739  
    2323 */ 
    2424 
     25/* 
     26 * Implementation of the FFADO external C API 
     27 */ 
     28 
    2529#include "config.h" 
    2630 
     
    3135#include "devicemanager.h" 
    3236#include "ffadodevice.h" 
     37#include "libstreaming/StreamProcessorManager.h" 
    3338 
    3439#include <stdio.h> 
    3540#include <stdlib.h> 
    3641#include <string.h> 
     42#include <assert.h> 
     43#include <string> 
    3744 
    3845DECLARE_GLOBAL_DEBUG_MODULE; 
     
    6370} 
    6471 
    65  
    6672int 
    6773ffado_get_api_version() { 
    6874    return FFADO_API_VERSION; 
    69 } 
    70  
    71 ffado_handle_t 
    72 ffado_new_handle( int port ) 
    73 { 
    74     ffado_handle_t handle = new struct ffado_handle; 
    75     if (! handle ) { 
    76         debugFatal( "Could not allocate memory for new handle\n" ); 
    77         return 0; 
    78     } 
    79  
    80     handle->m_deviceManager = new DeviceManager(); 
    81     if ( !handle->m_deviceManager ) { 
    82         debugFatal( "Could not allocate device manager\n" ); 
    83         delete handle; 
    84         return 0; 
    85     } 
    86     if ( !handle->m_deviceManager->initialize( port ) ) { 
    87         debugFatal( "Could not initialize device manager\n" ); 
    88         delete handle->m_deviceManager; 
    89         delete handle; 
    90         return 0; 
    91     } 
    92     return handle; 
    93 } 
    94  
    95 int 
    96 ffado_destroy_handle( ffado_handle_t ffado_handle ) 
    97 { 
    98     delete ffado_handle->m_deviceManager; 
    99     delete ffado_handle; 
    100     return 0; 
    101 } 
    102  
    103 int 
    104 ffado_discover_devices( ffado_handle_t ffado_handle, int verbose ) 
    105 { 
    106     if (verbose) { 
    107         ffado_handle->m_deviceManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 
    108    } 
    109     return ffado_handle->m_deviceManager->discover()? 0 : -1; 
    110 } 
    111  
    112 int 
    113 ffado_node_is_valid_ffado_device( ffado_handle_t ffado_handle, int node_id ) 
    114 { 
    115     return ffado_handle->m_deviceManager->isValidNode( node_id ); 
    116 } 
    117  
    118 int 
    119 ffado_get_nb_devices_on_bus( ffado_handle_t ffado_handle ) 
    120 { 
    121     return ffado_handle->m_deviceManager->getNbDevices(); 
    122 } 
    123  
    124 int 
    125 ffado_get_device_node_id( ffado_handle_t ffado_handle, int device_nr ) 
    126 { 
    127     return ffado_handle->m_deviceManager->getDeviceNodeId(device_nr); 
    128 } 
    129  
    130 int 
    131 ffado_set_samplerate( ffado_handle_t ffado_handle, int node_id, int samplerate ) 
    132 { 
    133     FFADODevice* avDevice = ffado_handle->m_deviceManager->getAvDevice( node_id ); 
    134     if ( avDevice ) { 
    135         if ( avDevice->setSamplingFrequency( samplerate ) ) { 
    136             return ffado_handle->m_deviceManager->discover()? 0 : -1; 
    137         } 
    138     } 
    139     return -1; 
    14075} 
    14176 
     
    14681    AVC::AVCCommand::setSleepAfterAVCCommand( time ); 
    14782} 
     83 
     84 
     85using namespace Streaming; 
     86 
     87struct _ffado_device 
     88{ 
     89    DeviceManager * m_deviceManager; 
     90    StreamProcessorManager *processorManager; 
     91 
     92    ffado_options_t options; 
     93    ffado_device_info_t device_info; 
     94}; 
     95 
     96ffado_device_t *ffado_streaming_init (ffado_device_info_t device_info, ffado_options_t options) { 
     97    unsigned int i=0; 
     98    setDebugLevel(options.verbose); 
     99 
     100    struct _ffado_device *dev = new struct _ffado_device; 
     101 
     102    debugWarning("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__); 
     103 
     104    if(!dev) { 
     105        debugFatal( "Could not allocate streaming device\n" ); 
     106        return 0; 
     107    } 
     108 
     109    memcpy((void *)&dev->options, (void *)&options, sizeof(dev->options)); 
     110 
     111    dev->m_deviceManager = new DeviceManager(); 
     112    if ( !dev->m_deviceManager ) { 
     113        debugFatal( "Could not allocate device manager\n" ); 
     114        delete dev; 
     115        return 0; 
     116    } 
     117 
     118    dev->m_deviceManager->setVerboseLevel(dev->options.verbose); 
     119    if ( !dev->m_deviceManager->initialize() ) { 
     120        debugFatal( "Could not initialize device manager\n" ); 
     121        delete dev->m_deviceManager; 
     122        delete dev; 
     123        return 0; 
     124    } 
     125 
     126    for (i = 0; i < device_info.nb_device_spec_strings; i++) { 
     127        char *s = device_info.device_spec_strings[i]; 
     128        if ( !dev->m_deviceManager->addSpecString(s) ) {  
     129            debugFatal( "Could not add spec string %s to device manager\n", s ); 
     130            delete dev->m_deviceManager; 
     131            delete dev; 
     132            return 0; 
     133        } 
     134    } 
     135 
     136 
     137    // create a processor manager to manage the actual stream 
     138    // processors 
     139    dev->processorManager = new StreamProcessorManager( dev->options.period_size,  
     140                                                        dev->options.sample_rate, 
     141                                                        dev->options.nb_buffers); 
     142    if(!dev->processorManager) { 
     143            debugFatal("Could not create StreamProcessorManager\n"); 
     144            delete dev->m_deviceManager; 
     145            delete dev; 
     146            return 0; 
     147    } 
     148 
     149    dev->processorManager->setThreadParameters(dev->options.realtime, dev->options.packetizer_priority); 
     150 
     151    dev->processorManager->setVerboseLevel(dev->options.verbose); 
     152    if(!dev->processorManager->init()) { 
     153            debugFatal("Could not init StreamProcessorManager\n"); 
     154            delete dev->processorManager; 
     155            delete dev->m_deviceManager; 
     156            delete dev; 
     157            return 0; 
     158    } 
     159 
     160    // set slave mode option 
     161    bool slaveMode=(dev->options.slave_mode != 0); 
     162    debugOutput(DEBUG_LEVEL_VERBOSE, "setting slave mode to %d\n", slaveMode); 
     163    if(!dev->m_deviceManager->setOption("slaveMode", slaveMode)) { 
     164            debugWarning("Failed to set slave mode option\n"); 
     165    } 
     166    // set snoop mode option 
     167    bool snoopMode=(dev->options.snoop_mode != 0); 
     168    debugOutput(DEBUG_LEVEL_VERBOSE, "setting snoop mode to %d\n", snoopMode); 
     169    if(!dev->m_deviceManager->setOption("snoopMode", snoopMode)) { 
     170            debugWarning("Failed to set snoop mode option\n"); 
     171    } 
     172 
     173    // discover the devices on the bus 
     174    if(!dev->m_deviceManager->discover()) { 
     175            debugFatal("Could not discover devices\n"); 
     176            delete dev->processorManager; 
     177            delete dev->m_deviceManager; 
     178            delete dev; 
     179            return 0; 
     180    } 
     181 
     182    // are there devices on the bus? 
     183    if(dev->m_deviceManager->getAvDeviceCount()==0) { 
     184            debugFatal("There are no devices on the bus\n"); 
     185            delete dev->processorManager; 
     186            delete dev->m_deviceManager; 
     187            delete dev; 
     188            return 0; 
     189    } 
     190 
     191    // iterate over the found devices 
     192    // add the stream processors of the devices to the managers 
     193    for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 
     194        FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 
     195        assert(device); 
     196 
     197        debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device); 
     198 
     199        if (!device->lock()) { 
     200            debugWarning("Could not lock device, skipping device (%p)!\n", device); 
     201            continue; 
     202        } 
     203 
     204        debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n", 
     205                    dev->options.sample_rate, device); 
     206 
     207        // Set the device's sampling rate to that requested 
     208        // FIXME: does this really belong here?  If so we need to handle errors. 
     209        if (!device->setSamplingFrequency(dev->options.sample_rate)) { 
     210            debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n", 
     211                        dev->options.sample_rate, device); 
     212 
     213            // try again: 
     214            if (!device->setSamplingFrequency(dev->options.sample_rate)) { 
     215                delete dev->processorManager; 
     216                delete dev->m_deviceManager; 
     217                delete dev; 
     218                debugFatal("Could not set sampling frequency to %d\n",dev->options.sample_rate); 
     219                return 0; 
     220            } 
     221        } 
     222 
     223        // prepare the device 
     224        device->prepare(); 
     225        int j=0; 
     226        for(j=0; j<device->getStreamCount();j++) { 
     227            StreamProcessor *streamproc=device->getStreamProcessorByIndex(j); 
     228            debugOutput(DEBUG_LEVEL_VERBOSE, "Registering stream processor %d of device %d with processormanager\n",j,i); 
     229            if (!dev->processorManager->registerProcessor(streamproc)) { 
     230                delete dev->processorManager; 
     231                delete dev->m_deviceManager; 
     232                delete dev; 
     233                debugFatal("Could not register stream processor (%p) with the Processor manager\n", streamproc); 
     234                return 0; 
     235            } 
     236        } 
     237    } 
     238 
     239    // set the sync source 
     240    if (!dev->processorManager->setSyncSource(dev->m_deviceManager->getSyncSource())) { 
     241        debugWarning("Could not set processorManager sync source (%p)\n", 
     242            dev->m_deviceManager->getSyncSource()); 
     243    } 
     244 
     245    // we are ready! 
     246    debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n\n"); 
     247    return dev; 
     248 
     249} 
     250 
     251int ffado_streaming_prepare(ffado_device_t *dev) { 
     252    debugOutput(DEBUG_LEVEL_VERBOSE, "Preparing...\n"); 
     253 
     254    if (!dev->processorManager->prepare()) { 
     255        debugFatal("Could not prepare streaming...\n"); 
     256        return false; 
     257    } 
     258 
     259    return true; 
     260} 
     261 
     262void ffado_streaming_finish(ffado_device_t *dev) { 
     263    unsigned int i=0; 
     264 
     265    assert(dev); 
     266 
     267    // iterate over the found devices 
     268    for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 
     269        FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 
     270        assert(device); 
     271 
     272        debugOutput(DEBUG_LEVEL_VERBOSE, "Unlocking device (%p)\n", device); 
     273 
     274        if (!device->unlock()) { 
     275            debugWarning("Could not unlock device (%p)!\n", device); 
     276        } 
     277    } 
     278 
     279    delete dev->processorManager; 
     280    delete dev->m_deviceManager; 
     281    delete dev; 
     282 
     283    return; 
     284} 
     285 
     286int ffado_streaming_start(ffado_device_t *dev) { 
     287    unsigned int i=0; 
     288    debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Start -------------\n"); 
     289 
     290    // create the connections for all devices 
     291    // iterate over the found devices 
     292    // add the stream processors of the devices to the managers 
     293    for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 
     294        FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 
     295        assert(device); 
     296 
     297        int j=0; 
     298        for(j=0; j<device->getStreamCount();j++) { 
     299        debugOutput(DEBUG_LEVEL_VERBOSE,"Starting stream %d of device %d\n",j,i); 
     300            // start the stream 
     301            if (!device->startStreamByIndex(j)) { 
     302                debugWarning("Could not start stream %d of device %d\n",j,i); 
     303                continue; 
     304            } 
     305        } 
     306 
     307        if (!device->enableStreaming()) { 
     308            debugWarning("Could not enable streaming on device %d!\n",i); 
     309        } 
     310    } 
     311 
     312    if(dev->processorManager->start()) { 
     313        return 0; 
     314    } else { 
     315        ffado_streaming_stop(dev); 
     316        return -1; 
     317    } 
     318} 
     319 
     320int ffado_streaming_stop(ffado_device_t *dev) { 
     321    unsigned int i; 
     322    debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Stop -------------\n"); 
     323 
     324    dev->processorManager->stop(); 
     325 
     326    // create the connections for all devices 
     327    // iterate over the found devices 
     328    // add the stream processors of the devices to the managers 
     329    for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { 
     330        FFADODevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 
     331        assert(device); 
     332 
     333        if (!device->disableStreaming()) { 
     334            debugWarning("Could not disable streaming on device %d!\n",i); 
     335        } 
     336 
     337        int j=0; 
     338        for(j=0; j<device->getStreamCount();j++) { 
     339            debugOutput(DEBUG_LEVEL_VERBOSE,"Stopping stream %d of device %d\n",j,i); 
     340            // stop the stream 
     341            // start the stream 
     342            if (!device->stopStreamByIndex(j)) { 
     343                debugWarning("Could not stop stream %d of device %d\n",j,i); 
     344                continue; 
     345            } 
     346        } 
     347    } 
     348 
     349    return 0; 
     350} 
     351 
     352int ffado_streaming_reset(ffado_device_t *dev) { 
     353    debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Reset -------------\n"); 
     354 
     355    // dev->processorManager->reset(); 
     356 
     357    return 0; 
     358} 
     359 
     360int ffado_streaming_wait(ffado_device_t *dev) { 
     361    static int periods=0; 
     362    static int periods_print=0; 
     363    static int xruns=0; 
     364 
     365    periods++; 
     366    if(periods>periods_print) { 
     367        debugOutputShort(DEBUG_LEVEL_VERBOSE, "\nffado_streaming_wait\n"); 
     368        debugOutputShort(DEBUG_LEVEL_VERBOSE, "============================================\n"); 
     369        debugOutputShort(DEBUG_LEVEL_VERBOSE, "Xruns: %d\n",xruns); 
     370        debugOutputShort(DEBUG_LEVEL_VERBOSE, "============================================\n"); 
     371        dev->processorManager->dumpInfo(); 
     372        debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n"); 
     373        periods_print+=100; 
     374    } 
     375 
     376    if(dev->processorManager->waitForPeriod()) { 
     377        return dev->options.period_size; 
     378    } else { 
     379        debugWarning("XRUN detected\n"); 
     380 
     381        // do xrun recovery 
     382        dev->processorManager->handleXrun(); 
     383        xruns++; 
     384        return -1; 
     385    } 
     386} 
     387 
     388int ffado_streaming_transfer_capture_buffers(ffado_device_t *dev) { 
     389    return dev->processorManager->transfer(StreamProcessor::ePT_Receive); 
     390} 
     391 
     392int ffado_streaming_transfer_playback_buffers(ffado_device_t *dev) { 
     393    return dev->processorManager->transfer(StreamProcessor::ePT_Transmit); 
     394} 
     395 
     396int ffado_streaming_transfer_buffers(ffado_device_t *dev) { 
     397    return dev->processorManager->transfer(); 
     398} 
     399 
     400 
     401int ffado_streaming_write(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 
     402    Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 
     403    // use an assert here performancewise, 
     404    // it should already have failed before, if not correct 
     405    assert(p); 
     406 
     407    return p->writeEvents((void *)buffer, nsamples); 
     408} 
     409 
     410int ffado_streaming_read(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 
     411    Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 
     412    // use an assert here performancewise, 
     413    // it should already have failed before, if not correct 
     414    assert(p); 
     415 
     416    return p->readEvents((void *)buffer, nsamples); 
     417} 
     418 
     419int ffado_streaming_get_nb_capture_streams(ffado_device_t *dev) { 
     420    return dev->processorManager->getPortCount(Port::E_Capture); 
     421} 
     422 
     423int ffado_streaming_get_nb_playback_streams(ffado_device_t *dev) { 
     424    return dev->processorManager->getPortCount(Port::E_Playback); 
     425} 
     426 
     427int ffado_streaming_get_capture_stream_name(ffado_device_t *dev, int i, char* buffer, size_t buffersize) { 
     428    Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 
     429    if(!p) { 
     430        debugWarning("Could not get capture port at index %d\n",i); 
     431        return -1; 
     432    } 
     433 
     434    std::string name=p->getName(); 
     435    if (!strncpy(buffer, name.c_str(), buffersize)) { 
     436        debugWarning("Could not copy name\n"); 
     437        return -1; 
     438    } else return 0; 
     439} 
     440 
     441int ffado_streaming_get_playback_stream_name(ffado_device_t *dev, int i, char* buffer, size_t buffersize) { 
     442    Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 
     443    if(!p) { 
     444        debugWarning("Could not get playback port at index %d\n",i); 
     445        return -1; 
     446    } 
     447 
     448    std::string name=p->getName(); 
     449    if (!strncpy(buffer, name.c_str(), buffersize)) { 
     450        debugWarning("Could not copy name\n"); 
     451        return -1; 
     452    } else return 0; 
     453} 
     454 
     455ffado_streaming_stream_type ffado_streaming_get_capture_stream_type(ffado_device_t *dev, int i) { 
     456    Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 
     457    if(!p) { 
     458        debugWarning("Could not get capture port at index %d\n",i); 
     459        return ffado_stream_type_invalid; 
     460    } 
     461    switch(p->getPortType()) { 
     462    case Port::E_Audio: 
     463        return ffado_stream_type_audio; 
     464    case Port::E_Midi: 
     465        return ffado_stream_type_midi; 
     466    case Port::E_Control: 
     467        return ffado_stream_type_control; 
     468    default: 
     469        return ffado_stream_type_unknown; 
     470    } 
     471} 
     472 
     473ffado_streaming_stream_type ffado_streaming_get_playback_stream_type(ffado_device_t *dev, int i) { 
     474    Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 
     475    if(!p) { 
     476        debugWarning("Could not get playback port at index %d\n",i); 
     477        return ffado_stream_type_invalid; 
     478    } 
     479    switch(p->getPortType()) { 
     480    case Port::E_Audio: 
     481        return ffado_stream_type_audio; 
     482    case Port::E_Midi: 
     483        return ffado_stream_type_midi; 
     484    case Port::E_Control: 
     485        return ffado_stream_type_control; 
     486    default: 
     487        return ffado_stream_type_unknown; 
     488    } 
     489} 
     490 
     491int ffado_streaming_set_stream_buffer_type(ffado_device_t *dev, int i, 
     492    ffado_streaming_buffer_type t, enum Port::E_Direction direction) { 
     493 
     494    Port *p=dev->processorManager->getPortByIndex(i, direction); 
     495    if(!p) { 
     496        debugWarning("Could not get %s port at index %d\n", 
     497            (direction==Port::E_Playback?"Playback":"Capture"),i); 
     498        return -1; 
     499    } 
     500 
     501    switch(t) { 
     502    case ffado_buffer_type_int24: 
     503        if (!p->setDataType(Port::E_Int24)) { 
     504            debugWarning("%s: Could not set data type to Int24\n",p->getName().c_str()); 
     505            return -1; 
     506        } 
     507        if (!p->setBufferType(Port::E_PointerBuffer)) { 
     508            debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 
     509            return -1; 
     510        } 
     511        break; 
     512    case ffado_buffer_type_float: 
     513        if (!p->setDataType(Port::E_Float)) { 
     514            debugWarning("%s: Could not set data type to Float\n",p->getName().c_str()); 
     515            return -1; 
     516        } 
     517        if (!p->setBufferType(Port::E_PointerBuffer)) { 
     518            debugWarning("%s: Could not set buffer type to Pointerbuffer\n",p->getName().c_str()); 
     519            return -1; 
     520        } 
     521        break; 
     522    case ffado_buffer_type_midi: 
     523        if (!p->setDataType(Port::E_MidiEvent)) { 
     524            debugWarning("%s: Could not set data type to MidiEvent\n",p->getName().c_str()); 
     525            return -1; 
     526        } 
     527        if (!p->setBufferType(Port::E_RingBuffer)) { 
     528            debugWarning("%s: Could not set buffer type to Ringbuffer\n",p->getName().c_str()); 
     529            return -1; 
     530        } 
     531        break; 
     532    default: 
     533        debugWarning("%s: Unsupported buffer type\n",p->getName().c_str()); 
     534        return -1; 
     535    } 
     536    return 0; 
     537 
     538} 
     539 
     540int ffado_streaming_set_playback_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t) { 
     541    return ffado_streaming_set_stream_buffer_type(dev, i, t, Port::E_Playback); 
     542} 
     543 
     544int ffado_streaming_set_capture_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t) { 
     545    return ffado_streaming_set_stream_buffer_type(dev, i, t, Port::E_Capture); 
     546} 
     547 
     548int ffado_streaming_stream_onoff(ffado_device_t *dev, int i, 
     549    int on, enum Port::E_Direction direction) { 
     550    Port *p=dev->processorManager->getPortByIndex(i, direction); 
     551    if(!p) { 
     552        debugWarning("Could not get %s port at index %d\n", 
     553            (direction==Port::E_Playback?"Playback":"Capture"),i); 
     554        return -1; 
     555    } 
     556    if(on) { 
     557        p->enable(); 
     558    } else { 
     559        p->disable(); 
     560    } 
     561    return 0; 
     562} 
     563 
     564int ffado_streaming_playback_stream_onoff(ffado_device_t *dev, int number, int on) { 
     565    return ffado_streaming_stream_onoff(dev, number, on, Port::E_Playback); 
     566} 
     567 
     568int ffado_streaming_capture_stream_onoff(ffado_device_t *dev, int number, int on) { 
     569    return ffado_streaming_stream_onoff(dev, number, on, Port::E_Capture); 
     570} 
     571 
     572// TODO: the way port buffers are set in the C api doesn't satisfy me 
     573int ffado_streaming_set_capture_stream_buffer(ffado_device_t *dev, int i, char *buff) { 
     574        Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 
     575 
     576        // use an assert here performancewise, 
     577        // it should already have failed before, if not correct 
     578        assert(p); 
     579 
     580        p->useExternalBuffer(true); 
     581        p->setExternalBufferAddress((void *)buff); 
     582 
     583        return 0; 
     584 
     585} 
     586 
     587int ffado_streaming_set_playback_stream_buffer(ffado_device_t *dev, int i, char *buff) { 
     588        Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 
     589        // use an assert here performancewise, 
     590        // it should already have failed before, if not correct 
     591        assert(p); 
     592 
     593        p->useExternalBuffer(true); 
     594        p->setExternalBufferAddress((void *)buff); 
     595 
     596        return 0; 
     597}