Changeset 445 for trunk/libffado/src/ffado_streaming.cpp
- Timestamp:
- 04/02/07 12:35:17 (17 years ago)
- Files:
-
- trunk/libffado/src/ffado_streaming.cpp (modified) (30 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/src/ffado_streaming.cpp
r442 r445 1 /* $Id$ */2 3 1 /* 4 * FreeBob Streaming API 5 * FreeBob = Firewire (pro-)audio for linux 6 * 7 * http://freebob.sf.net 8 * 9 * Copyright (C) 2005,2006 Pieter Palmers <pieterpalmers@users.sourceforge.net> 10 * 11 * This program is free software {} you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation {} either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY {} without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program {} if not, write to the Free Software 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 25 * 26 * 27 */ 28 29 /* freebob_streaming.c 30 * 31 * Implementation of the FreeBob Streaming API 32 * 33 */ 34 35 #include "libfreebob/freebob.h" 36 #include "libfreebob/freebob_streaming.h" 2 * Copyright (C) 2005-2007 by Pieter Palmers 3 * 4 * This file is part of FFADO 5 * FFADO = Free Firewire (pro-)audio drivers for linux 6 * 7 * FFADO is based upon FreeBoB 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License version 2.1, as published by the Free Software Foundation; 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 * MA 02110-1301 USA 22 */ 23 24 /* 25 * Implementation of the FFADO Streaming API 26 */ 27 28 #include "libffado/ffado.h" 37 29 #include "devicemanager.h" 38 30 #include "iavdevice.h" … … 53 45 using namespace Streaming; 54 46 55 struct _f reebob_device47 struct _ffado_device 56 48 { 57 49 DeviceManager * m_deviceManager; 58 50 StreamProcessorManager *processorManager; 59 51 60 f reebob_options_t options;61 f reebob_device_info_t device_info;62 }; 63 64 f reebob_device_t *freebob_streaming_init (freebob_device_info_t *device_info, freebob_options_t options) {52 ffado_options_t options; 53 ffado_device_info_t device_info; 54 }; 55 56 ffado_device_t *ffado_streaming_init (ffado_device_info_t *device_info, ffado_options_t options) { 65 57 unsigned int i=0; 66 58 67 struct _f reebob_device *dev = new struct _freebob_device;68 69 debugFatal("%s built %s %s\n", f reebob_get_version(), __DATE__, __TIME__);59 struct _ffado_device *dev = new struct _ffado_device; 60 61 debugFatal("%s built %s %s\n", ffado_get_version(), __DATE__, __TIME__); 70 62 71 63 if(!dev) { … … 83 75 return 0; 84 76 } 85 77 86 78 dev->m_deviceManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 87 79 if ( !dev->m_deviceManager->initialize( dev->options.port ) ) { … … 93 85 94 86 // create a processor manager to manage the actual stream 95 // processors 87 // processors 96 88 dev->processorManager = new StreamProcessorManager(dev->options.period_size,dev->options.nb_buffers); 97 89 if(!dev->processorManager) { … … 101 93 return 0; 102 94 } 103 95 104 96 dev->processorManager->setThreadParameters(dev->options.realtime, dev->options.packetizer_priority); 105 97 106 98 dev->processorManager->setVerboseLevel(DEBUG_LEVEL_VERBOSE); 107 99 if(!dev->processorManager->init()) { … … 112 104 return 0; 113 105 } 114 106 115 107 // set slave mode option 116 108 bool slaveMode=(dev->options.slave_mode != 0); … … 125 117 debugWarning("Failed to set snoop mode option\n"); 126 118 } 127 119 128 120 // discover the devices on the bus 129 121 if(!dev->m_deviceManager->discover()) { … … 134 126 return 0; 135 127 } 136 128 137 129 // are there devices on the bus? 138 130 if(dev->m_deviceManager->getAvDeviceCount()==0) { … … 143 135 return 0; 144 136 } 145 137 146 138 // iterate over the found devices 147 139 // add the stream processors of the devices to the managers … … 151 143 152 144 debugOutput(DEBUG_LEVEL_VERBOSE, "Locking device (%p)\n", device); 153 145 154 146 if (!device->lock()) { 155 147 debugWarning("Could not lock device, skipping device (%p)!\n", device); 156 148 continue; 157 149 } 158 159 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n", 150 151 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n", 160 152 dev->options.sample_rate, device); 161 153 162 154 // Set the device's sampling rate to that requested 163 155 // FIXME: does this really belong here? If so we need to handle errors. 164 156 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 165 debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n", 157 debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n", 166 158 dev->options.sample_rate, device); 167 159 168 160 // try again: 169 161 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { … … 188 180 } 189 181 } 190 182 191 183 // set the sync source 192 184 if (!dev->processorManager->setSyncSource(dev->m_deviceManager->getSyncSource())) { … … 201 193 } 202 194 203 int f reebob_streaming_prepare(freebob_device_t *dev) {195 int ffado_streaming_prepare(ffado_device_t *dev) { 204 196 debugOutput(DEBUG_LEVEL_VERBOSE, "Preparing...\n"); 205 197 206 198 if (!dev->processorManager->prepare()) { 207 199 debugFatal("Could not prepare streaming...\n"); … … 212 204 } 213 205 214 void f reebob_streaming_finish(freebob_device_t *dev) {206 void ffado_streaming_finish(ffado_device_t *dev) { 215 207 unsigned int i=0; 216 208 217 209 assert(dev); 218 210 219 211 // iterate over the found devices 220 212 for(i=0;i<dev->m_deviceManager->getAvDeviceCount();i++) { … … 228 220 } 229 221 } 230 222 231 223 delete dev->processorManager; 232 224 delete dev->m_deviceManager; … … 236 228 } 237 229 238 int f reebob_streaming_start(freebob_device_t *dev) {230 int ffado_streaming_start(ffado_device_t *dev) { 239 231 unsigned int i=0; 240 232 debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Start -------------\n"); 241 233 242 234 // create the connections for all devices 243 235 // iterate over the found devices … … 246 238 IAvDevice *device=dev->m_deviceManager->getAvDeviceByIndex(i); 247 239 assert(device); 248 240 249 241 int j=0; 250 242 for(j=0; j<device->getStreamCount();j++) { … … 265 257 return 0; 266 258 } else { 267 f reebob_streaming_stop(dev);268 return -1; 269 } 270 } 271 272 int f reebob_streaming_stop(freebob_device_t *dev) {259 ffado_streaming_stop(dev); 260 return -1; 261 } 262 } 263 264 int ffado_streaming_stop(ffado_device_t *dev) { 273 265 unsigned int i; 274 266 debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Stop -------------\n"); … … 286 278 debugWarning("Could not disable streaming on device %d!\n",i); 287 279 } 288 280 289 281 int j=0; 290 282 for(j=0; j<device->getStreamCount();j++) { … … 302 294 } 303 295 304 int f reebob_streaming_reset(freebob_device_t *dev) {296 int ffado_streaming_reset(ffado_device_t *dev) { 305 297 debugOutput(DEBUG_LEVEL_VERBOSE,"------------- Reset -------------\n"); 306 298 … … 310 302 } 311 303 312 int f reebob_streaming_wait(freebob_device_t *dev) {304 int ffado_streaming_wait(ffado_device_t *dev) { 313 305 static int periods=0; 314 306 static int periods_print=0; 315 307 static int xruns=0; 316 308 317 309 periods++; 318 310 if(periods>periods_print) { 319 debugOutputShort(DEBUG_LEVEL_VERBOSE, "\nf reebob_streaming_wait\n");311 debugOutputShort(DEBUG_LEVEL_VERBOSE, "\nffado_streaming_wait\n"); 320 312 debugOutputShort(DEBUG_LEVEL_VERBOSE, "============================================\n"); 321 313 debugOutputShort(DEBUG_LEVEL_VERBOSE, "Xruns: %d\n",xruns); … … 325 317 periods_print+=100; 326 318 } 327 319 328 320 if(dev->processorManager->waitForPeriod()) { 329 321 return dev->options.period_size; 330 322 } else { 331 323 debugWarning("XRUN detected\n"); 332 324 333 325 // do xrun recovery 334 326 dev->processorManager->handleXrun(); … … 338 330 } 339 331 340 int f reebob_streaming_transfer_capture_buffers(freebob_device_t *dev) {332 int ffado_streaming_transfer_capture_buffers(ffado_device_t *dev) { 341 333 return dev->processorManager->transfer(StreamProcessor::E_Receive); 342 334 } 343 335 344 int f reebob_streaming_transfer_playback_buffers(freebob_device_t *dev) {336 int ffado_streaming_transfer_playback_buffers(ffado_device_t *dev) { 345 337 return dev->processorManager->transfer(StreamProcessor::E_Transmit); 346 338 } 347 339 348 int f reebob_streaming_transfer_buffers(freebob_device_t *dev) {340 int ffado_streaming_transfer_buffers(ffado_device_t *dev) { 349 341 return dev->processorManager->transfer(); 350 342 } 351 343 352 344 353 int f reebob_streaming_write(freebob_device_t *dev, int i, freebob_sample_t *buffer, int nsamples) {345 int ffado_streaming_write(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 354 346 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 355 // use an assert here performancewise, 347 // use an assert here performancewise, 356 348 // it should already have failed before, if not correct 357 assert(p); 358 349 assert(p); 350 359 351 return p->writeEvents((void *)buffer, nsamples); 360 352 } 361 353 362 int f reebob_streaming_read(freebob_device_t *dev, int i, freebob_sample_t *buffer, int nsamples) {354 int ffado_streaming_read(ffado_device_t *dev, int i, ffado_sample_t *buffer, int nsamples) { 363 355 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 364 // use an assert here performancewise, 356 // use an assert here performancewise, 365 357 // it should already have failed before, if not correct 366 assert(p); 367 358 assert(p); 359 368 360 return p->readEvents((void *)buffer, nsamples); 369 361 } 370 362 371 int f reebob_streaming_get_nb_capture_streams(freebob_device_t *dev) {363 int ffado_streaming_get_nb_capture_streams(ffado_device_t *dev) { 372 364 return dev->processorManager->getPortCount(Port::E_Capture); 373 365 } 374 366 375 int f reebob_streaming_get_nb_playback_streams(freebob_device_t *dev) {367 int ffado_streaming_get_nb_playback_streams(ffado_device_t *dev) { 376 368 return dev->processorManager->getPortCount(Port::E_Playback); 377 369 } 378 370 379 int f reebob_streaming_get_capture_stream_name(freebob_device_t *dev, int i, char* buffer, size_t buffersize) {371 int ffado_streaming_get_capture_stream_name(ffado_device_t *dev, int i, char* buffer, size_t buffersize) { 380 372 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 381 373 if(!p) { … … 391 383 } 392 384 393 int f reebob_streaming_get_playback_stream_name(freebob_device_t *dev, int i, char* buffer, size_t buffersize) {385 int ffado_streaming_get_playback_stream_name(ffado_device_t *dev, int i, char* buffer, size_t buffersize) { 394 386 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 395 387 if(!p) { … … 405 397 } 406 398 407 f reebob_streaming_stream_type freebob_streaming_get_capture_stream_type(freebob_device_t *dev, int i) {399 ffado_streaming_stream_type ffado_streaming_get_capture_stream_type(ffado_device_t *dev, int i) { 408 400 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 409 401 if(!p) { 410 402 debugWarning("Could not get capture port at index %d\n",i); 411 return f reebob_stream_type_invalid;403 return ffado_stream_type_invalid; 412 404 } 413 405 switch(p->getPortType()) { 414 406 case Port::E_Audio: 415 return f reebob_stream_type_audio;407 return ffado_stream_type_audio; 416 408 case Port::E_Midi: 417 return f reebob_stream_type_midi;409 return ffado_stream_type_midi; 418 410 case Port::E_Control: 419 return f reebob_stream_type_control;411 return ffado_stream_type_control; 420 412 default: 421 return f reebob_stream_type_unknown;422 } 423 } 424 425 f reebob_streaming_stream_type freebob_streaming_get_playback_stream_type(freebob_device_t *dev, int i) {413 return ffado_stream_type_unknown; 414 } 415 } 416 417 ffado_streaming_stream_type ffado_streaming_get_playback_stream_type(ffado_device_t *dev, int i) { 426 418 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 427 419 if(!p) { 428 420 debugWarning("Could not get playback port at index %d\n",i); 429 return f reebob_stream_type_invalid;421 return ffado_stream_type_invalid; 430 422 } 431 423 switch(p->getPortType()) { 432 424 case Port::E_Audio: 433 return f reebob_stream_type_audio;425 return ffado_stream_type_audio; 434 426 case Port::E_Midi: 435 return f reebob_stream_type_midi;427 return ffado_stream_type_midi; 436 428 case Port::E_Control: 437 return f reebob_stream_type_control;429 return ffado_stream_type_control; 438 430 default: 439 return f reebob_stream_type_unknown;440 } 441 } 442 443 int f reebob_streaming_set_stream_buffer_type(freebob_device_t *dev, int i,444 f reebob_streaming_buffer_type t, enum Port::E_Direction direction) {431 return ffado_stream_type_unknown; 432 } 433 } 434 435 int ffado_streaming_set_stream_buffer_type(ffado_device_t *dev, int i, 436 ffado_streaming_buffer_type t, enum Port::E_Direction direction) { 445 437 446 438 Port *p=dev->processorManager->getPortByIndex(i, direction); … … 450 442 return -1; 451 443 } 452 444 453 445 switch(t) { 454 case f reebob_buffer_type_int24:446 case ffado_buffer_type_int24: 455 447 if (!p->setDataType(Port::E_Int24)) { 456 448 debugWarning("%s: Could not set data type to Int24\n",p->getName().c_str()); … … 462 454 } 463 455 break; 464 case f reebob_buffer_type_float:456 case ffado_buffer_type_float: 465 457 if (!p->setDataType(Port::E_Float)) { 466 458 debugWarning("%s: Could not set data type to Float\n",p->getName().c_str()); … … 472 464 } 473 465 break; 474 case f reebob_buffer_type_midi:466 case ffado_buffer_type_midi: 475 467 if (!p->setDataType(Port::E_MidiEvent)) { 476 468 debugWarning("%s: Could not set data type to MidiEvent\n",p->getName().c_str()); … … 490 482 } 491 483 492 int f reebob_streaming_set_playback_buffer_type(freebob_device_t *dev, int i, freebob_streaming_buffer_type t) {493 return f reebob_streaming_set_stream_buffer_type(dev, i, t, Port::E_Playback);494 } 495 496 int f reebob_streaming_set_capture_buffer_type(freebob_device_t *dev, int i, freebob_streaming_buffer_type t) {497 return f reebob_streaming_set_stream_buffer_type(dev, i, t, Port::E_Capture);498 } 499 500 int f reebob_streaming_stream_onoff(freebob_device_t *dev, int i,484 int ffado_streaming_set_playback_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t) { 485 return ffado_streaming_set_stream_buffer_type(dev, i, t, Port::E_Playback); 486 } 487 488 int ffado_streaming_set_capture_buffer_type(ffado_device_t *dev, int i, ffado_streaming_buffer_type t) { 489 return ffado_streaming_set_stream_buffer_type(dev, i, t, Port::E_Capture); 490 } 491 492 int ffado_streaming_stream_onoff(ffado_device_t *dev, int i, 501 493 int on, enum Port::E_Direction direction) { 502 494 Port *p=dev->processorManager->getPortByIndex(i, direction); … … 514 506 } 515 507 516 int f reebob_streaming_playback_stream_onoff(freebob_device_t *dev, int number, int on) {517 return f reebob_streaming_stream_onoff(dev, number, on, Port::E_Playback);518 } 519 520 int f reebob_streaming_capture_stream_onoff(freebob_device_t *dev, int number, int on) {521 return f reebob_streaming_stream_onoff(dev, number, on, Port::E_Capture);508 int ffado_streaming_playback_stream_onoff(ffado_device_t *dev, int number, int on) { 509 return ffado_streaming_stream_onoff(dev, number, on, Port::E_Playback); 510 } 511 512 int ffado_streaming_capture_stream_onoff(ffado_device_t *dev, int number, int on) { 513 return ffado_streaming_stream_onoff(dev, number, on, Port::E_Capture); 522 514 } 523 515 524 516 // TODO: the way port buffers are set in the C api doesn't satisfy me 525 int f reebob_streaming_set_capture_stream_buffer(freebob_device_t *dev, int i, char *buff) {517 int ffado_streaming_set_capture_stream_buffer(ffado_device_t *dev, int i, char *buff) { 526 518 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Capture); 527 528 // use an assert here performancewise, 519 520 // use an assert here performancewise, 529 521 // it should already have failed before, if not correct 530 assert(p); 531 522 assert(p); 523 532 524 p->useExternalBuffer(true); 533 525 p->setExternalBufferAddress((void *)buff); … … 537 529 } 538 530 539 int f reebob_streaming_set_playback_stream_buffer(freebob_device_t *dev, int i, char *buff) {531 int ffado_streaming_set_playback_stream_buffer(ffado_device_t *dev, int i, char *buff) { 540 532 Port *p=dev->processorManager->getPortByIndex(i, Port::E_Playback); 541 // use an assert here performancewise, 533 // use an assert here performancewise, 542 534 // it should already have failed before, if not correct 543 assert(p); 544 535 assert(p); 536 545 537 p->useExternalBuffer(true); 546 538 p->setExternalBufferAddress((void *)buff);