Changeset 721:b32c12ce040f in mediastreamer2
- Timestamp:
- Oct 10, 2009 2:16:06 PM (4 years ago)
- Branch:
- default
- File:
-
- 1 edited
-
linphone/mediastreamer2/src/aqsnd.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
linphone/mediastreamer2/src/aqsnd.c
r713 r721 61 61 #include "mediastreamer2/msfilter.h" 62 62 63 MSFilter *ms_aq_read_new(MSSndCard *card); 64 MSFilter *ms_aq_write_new(MSSndCard *card); 65 66 #define kSecondsPerBuffer 0.02 67 #define kNumberAudioDataBuffers 4 68 69 typedef struct AQData{ 70 int rate; 71 int bits; 72 bool_t stereo; 73 74 ms_mutex_t mutex; 75 queue_t rq; 76 bool_t read_started; 77 bool_t write_started; 78 79 AudioQueueRef readQueue; 80 AudioStreamBasicDescription readAudioFormat; 81 UInt32 readBufferByteSize; 82 AudioQueueRef writeQueue; 83 AudioStreamBasicDescription writeAudioFormat; 84 UInt32 writeBufferByteSize; 85 AudioQueueBufferRef writeBuffers[kNumberAudioDataBuffers]; 86 int curWriteBuffer; 87 MSBufferizer *bufferizer; 63 MSFilter *ms_aq_read_new(MSSndCard * card); 64 MSFilter *ms_aq_write_new(MSSndCard * card); 65 66 #define kSecondsPerBuffer 0.02 /*0.04 */ 67 #define kNumberAudioOutDataBuffers 4 68 #define kNumberAudioInDataBuffers 4 69 70 typedef struct AQData { 71 CFStringRef uidname; 72 AudioStreamBasicDescription devicereadFormat; 73 AudioStreamBasicDescription devicewriteFormat; 74 75 int rate; 76 int bits; 77 bool_t stereo; 78 79 ms_mutex_t mutex; 80 queue_t rq; 81 bool_t read_started; 82 bool_t write_started; 83 84 AudioConverterRef readAudioConverter; 85 AudioQueueRef readQueue; 86 AudioStreamBasicDescription readAudioFormat; 87 UInt32 readBufferByteSize; 88 89 AudioConverterRef writeAudioConverter; 90 AudioQueueRef writeQueue; 91 AudioStreamBasicDescription writeAudioFormat; 92 UInt32 writeBufferByteSize; 93 AudioQueueBufferRef writeBuffers[kNumberAudioOutDataBuffers]; 94 int curWriteBuffer; 95 MSBufferizer *bufferizer; 88 96 } AQData; 97 98 99 100 /* 101 mediastreamer2 function 102 */ 103 104 typedef struct AqSndDsCard { 105 CFStringRef uidname; 106 AudioStreamBasicDescription devicereadFormat; 107 AudioStreamBasicDescription devicewriteFormat; 108 int removed; 109 } AqSndDsCard; 110 111 static void aqcard_set_level(MSSndCard * card, MSSndCardMixerElem e, 112 int percent) 113 { 114 } 115 116 static int aqcard_get_level(MSSndCard * card, MSSndCardMixerElem e) 117 { 118 return 0; 119 } 120 121 static void aqcard_set_source(MSSndCard * card, MSSndCardCapture source) 122 { 123 } 124 125 static void aqcard_init(MSSndCard * card) 126 { 127 AqSndDsCard *c = (AqSndDsCard *) ms_new(AqSndDsCard, 1); 128 c->removed = 0; 129 card->data = c; 130 } 131 132 static void aqcard_uninit(MSSndCard * card) 133 { 134 AqSndDsCard *d = (AqSndDsCard *) card->data; 135 if (d->uidname != NULL) 136 CFRelease(d->uidname); 137 ms_free(d); 138 } 139 140 static void aqcard_detect(MSSndCardManager * m); 141 static MSSndCard *aqcard_duplicate(MSSndCard * obj); 142 143 MSSndCardDesc aq_card_desc = { 144 .driver_type = "AQ", 145 .detect = aqcard_detect, 146 .init = aqcard_init, 147 .set_level = aqcard_set_level, 148 .get_level = aqcard_get_level, 149 .set_capture = aqcard_set_source, 150 .set_control = NULL, 151 .get_control = NULL, 152 .create_reader = ms_aq_read_new, 153 .create_writer = ms_aq_write_new, 154 .uninit = aqcard_uninit, 155 .duplicate = aqcard_duplicate 156 }; 157 158 static MSSndCard *aqcard_duplicate(MSSndCard * obj) 159 { 160 MSSndCard *card = ms_snd_card_new(&aq_card_desc); 161 card->name = ms_strdup(obj->name); 162 card->data = ms_new(AqSndDsCard, 1); 163 memcpy(card->data, obj->data, sizeof(AqSndDsCard)); 164 return card; 165 } 166 167 static MSSndCard *aq_card_new(const char *name, CFStringRef uidname, 168 AudioStreamBasicDescription * 169 devicereadFormat, 170 AudioStreamBasicDescription * 171 devicewriteFormat, unsigned cap) 172 { 173 MSSndCard *card = ms_snd_card_new(&aq_card_desc); 174 AqSndDsCard *d = (AqSndDsCard *) card->data; 175 d->uidname = uidname; 176 memcpy(&d->devicereadFormat, devicereadFormat, 177 sizeof(AudioStreamBasicDescription)); 178 memcpy(&d->devicewriteFormat, devicewriteFormat, 179 sizeof(AudioStreamBasicDescription)); 180 card->name = ms_strdup(name); 181 card->capabilities = cap; 182 return card; 183 } 184 185 static void show_format(char *name, 186 AudioStreamBasicDescription * deviceFormat) 187 { 188 ms_debug("Format for %s", name); 189 ms_debug("mSampleRate = %g", deviceFormat->mSampleRate); 190 char *the4CCString = (char *) &deviceFormat->mFormatID; 191 char outName[5]; 192 outName[0] = the4CCString[0]; 193 outName[1] = the4CCString[1]; 194 outName[2] = the4CCString[2]; 195 outName[3] = the4CCString[3]; 196 outName[4] = 0; 197 ms_debug("mFormatID = %s", outName); 198 ms_debug("mFormatFlags = %08lX", deviceFormat->mFormatFlags); 199 ms_debug("mBytesPerPacket = %ld", deviceFormat->mBytesPerPacket); 200 ms_debug("mFramesPerPacket = %ld", deviceFormat->mFramesPerPacket); 201 ms_debug("mChannelsPerFrame = %ld", deviceFormat->mChannelsPerFrame); 202 ms_debug("mBytesPerFrame = %ld", deviceFormat->mBytesPerFrame); 203 ms_debug("mBitsPerChannel = %ld", deviceFormat->mBitsPerChannel); 204 } 205 206 static void aqcard_detect(MSSndCardManager * m) 207 { 208 OSStatus err; 209 UInt32 slen; 210 int count; 211 Boolean writable; 212 int i; 213 writable = 0; 214 slen = 0; 215 err = 216 AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &slen, 217 &writable); 218 if (err != kAudioHardwareNoError) { 219 ms_error("get kAudioHardwarePropertyDevices error %ld", err); 220 return; 221 } 222 AudioDeviceID V[slen / sizeof(AudioDeviceID)]; 223 err = 224 AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &slen, V); 225 if (err != kAudioHardwareNoError) { 226 ms_error("get kAudioHardwarePropertyDevices error %ld", err); 227 return; 228 } 229 count = slen / sizeof(AudioDeviceID); 230 for (i = 0; i < count; i++) { 231 char devname[256]; 232 char uidname[256]; 233 int cap = 0; 234 slen = 256; 235 err = 236 AudioDeviceGetProperty(V[i], 0, FALSE, 237 kAudioDevicePropertyDeviceName, &slen, 238 devname); 239 if (err != kAudioHardwareNoError) { 240 ms_error("get kAudioDevicePropertyDeviceName error %ld", err); 241 continue; 242 } 243 slen = strlen(devname); 244 /* trim whitespace */ 245 while ((slen > 0) && (devname[slen - 1] == ' ')) { 246 slen--; 247 } 248 devname[slen] = '\0'; 249 250 err = 251 AudioDeviceGetPropertyInfo(V[i], 0, FALSE, 252 kAudioDevicePropertyStreamConfiguration, 253 &slen, &writable); 254 if (err != kAudioHardwareNoError) { 255 ms_error("get kAudioDevicePropertyDeviceName error %ld", err); 256 continue; 257 } 258 AudioBufferList *buflist = ms_new(slen, 1); 259 if (buflist == NULL) { 260 ms_error("alloc AudioBufferList %ld", err); 261 continue; 262 } 263 264 err = 265 AudioDeviceGetProperty(V[i], 0, FALSE, 266 kAudioDevicePropertyStreamConfiguration, 267 &slen, buflist); 268 if (err != kAudioHardwareNoError) { 269 ms_error("get kAudioDevicePropertyDeviceName error %ld", err); 270 ms_free(buflist); 271 continue; 272 } 273 274 UInt32 j; 275 for (j = 0; j < buflist->mNumberBuffers; j++) { 276 if (buflist->mBuffers[j].mNumberChannels > 0) { 277 cap = MS_SND_CARD_CAP_PLAYBACK; 278 break; 279 } 280 } 281 282 ms_free(buflist); 283 284 err = 285 AudioDeviceGetPropertyInfo(V[i], 0, TRUE, 286 kAudioDevicePropertyStreamConfiguration, 287 &slen, &writable); 288 if (err != kAudioHardwareNoError) { 289 ms_error("get kAudioDevicePropertyDeviceName error %ld", err); 290 continue; 291 } 292 buflist = ms_new(slen, 1); 293 if (buflist == NULL) { 294 ms_error("alloc error %ld", err); 295 continue; 296 } 297 298 err = 299 AudioDeviceGetProperty(V[i], 0, TRUE, 300 kAudioDevicePropertyStreamConfiguration, 301 &slen, buflist); 302 if (err != kAudioHardwareNoError) { 303 ms_error("get kAudioDevicePropertyDeviceName error %ld", err); 304 ms_free(buflist); 305 continue; 306 } 307 308 for (j = 0; j < buflist->mNumberBuffers; j++) { 309 if (buflist->mBuffers[j].mNumberChannels > 0) { 310 cap |= MS_SND_CARD_CAP_CAPTURE; 311 break; 312 } 313 } 314 315 ms_free(buflist); 316 317 CFStringRef dUID; 318 dUID = NULL; 319 slen = sizeof(CFStringRef); 320 err = 321 AudioDeviceGetProperty(V[i], 0, false, 322 kAudioDevicePropertyDeviceUID, &slen, 323 &dUID); 324 if (err != kAudioHardwareNoError) { 325 ms_error("get kAudioHardwarePropertyDevices error %ld", err); 326 continue; 327 } 328 CFStringGetCString(dUID, uidname, 256, 329 CFStringGetSystemEncoding()); 330 ms_message("AQ: devname:%s uidname:%s", devname, uidname); 331 332 AudioStreamBasicDescription devicereadFormat; 333 AudioStreamBasicDescription devicewriteFormat; 334 slen = sizeof(devicewriteFormat); 335 err = AudioDeviceGetProperty(V[i], 0, false, 336 kAudioDevicePropertyStreamFormat, 337 &slen, &devicewriteFormat); 338 if (err == kAudioHardwareNoError) { 339 show_format("output device", &devicewriteFormat); 340 } 341 slen = sizeof(devicereadFormat); 342 err = AudioDeviceGetProperty(V[i], 0, true, 343 kAudioDevicePropertyStreamFormat, 344 &slen, &devicereadFormat); 345 if (err == kAudioHardwareNoError) { 346 show_format("input device", &devicereadFormat); 347 } 348 349 MSSndCard *card = aq_card_new(devname, dUID, &devicereadFormat, 350 &devicewriteFormat, cap); 351 ms_snd_card_manager_add_card(m, card); 352 } 353 } 354 89 355 90 356 /* … … 92 358 */ 93 359 94 static void readCallback ( 95 void *aqData, 96 AudioQueueRef inAQ, 97 AudioQueueBufferRef inBuffer, 98 const AudioTimeStamp *inStartTime, 99 UInt32 inNumPackets, 100 const AudioStreamPacketDescription *inPacketDesc 101 ) { 102 ms_debug("readCallback"); 103 AQData *d=(AQData*)aqData; 360 static void readCallback(void *aqData, 361 AudioQueueRef inAQ, 362 AudioQueueBufferRef inBuffer, 363 const AudioTimeStamp * inStartTime, 364 UInt32 inNumPackets, 365 const AudioStreamPacketDescription * inPacketDesc) 366 { 367 AQData *d = (AQData *) aqData; 104 368 OSStatus err; 105 106 // ms_debug("readCallback inNumPackets %d %d", inNumPackets, inBuffer->mAudioDataByteSize); 107 mblk_t *rm=NULL; 108 rm=allocb(inNumPackets*2,0); 109 memcpy(rm->b_wptr, inBuffer->mAudioData, inNumPackets*2); 110 rm->b_wptr += inNumPackets*2; 369 mblk_t *rm = NULL; 370 371 UInt32 len = 372 (inBuffer->mAudioDataByteSize * d->readAudioFormat.mSampleRate / 373 1) / d->devicereadFormat.mSampleRate / 374 d->devicereadFormat.mChannelsPerFrame; 375 111 376 ms_mutex_lock(&d->mutex); 112 putq(&d->rq,rm); 377 if (d->read_started == FALSE) { 378 ms_mutex_unlock(&d->mutex); 379 return; 380 } 381 382 rm = allocb(len, 0); 383 384 err = AudioConverterConvertBuffer(d->readAudioConverter, 385 inBuffer->mAudioDataByteSize, 386 inBuffer->mAudioData, 387 &len, rm->b_wptr); 388 if (err != noErr) { 389 ms_error("readCallback: AudioConverterConvertBuffer %d", err); 390 ms_warning("readCallback: inBuffer->mAudioDataByteSize = %d", 391 inBuffer->mAudioDataByteSize); 392 ms_warning("readCallback: outlen = %d", len); 393 ms_warning("readCallback: origlen = %i", 394 (inBuffer->mAudioDataByteSize * 395 d->readAudioFormat.mSampleRate / 1) / 396 d->devicereadFormat.mSampleRate / 397 d->devicereadFormat.mChannelsPerFrame); 398 freeb(rm); 399 } else { 400 rm->b_wptr += len; 401 putq(&d->rq, rm); 402 } 403 404 err = AudioQueueEnqueueBuffer(d->readQueue, inBuffer, 0, NULL); 405 if (err != noErr) { 406 ms_error("readCallback:AudioQueueEnqueueBuffer %d", err); 407 } 113 408 ms_mutex_unlock(&d->mutex); 114 rm=NULL;115 116 err = AudioQueueEnqueueBuffer (117 d->readQueue,118 inBuffer,119 0,120 NULL121 );122 if(err != noErr) {123 ms_error("readCallback:AudioQueueEnqueueBuffer %d", err);124 }125 409 } 126 410 … … 129 413 */ 130 414 131 static void writeCallback ( 132 void *aqData, 133 AudioQueueRef inAQ, 134 AudioQueueBufferRef inBuffer 135 ) { 136 ms_debug("writeCallback"); 137 AQData *d=(AQData*)aqData; 415 static void writeCallback(void *aqData, 416 AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) 417 { 418 AQData *d = (AQData *) aqData; 138 419 OSStatus err; 139 if(d->bufferizer->size >= d->writeBufferByteSize) { 140 ms_mutex_lock(&d->mutex); 141 ms_bufferizer_read(d->bufferizer, inBuffer->mAudioData, d->writeBufferByteSize); 420 421 int len = 422 (d->writeBufferByteSize * d->writeAudioFormat.mSampleRate / 2) / 423 d->devicewriteFormat.mSampleRate / 424 d->devicewriteFormat.mChannelsPerFrame; 425 426 ms_mutex_lock(&d->mutex); 427 if (d->write_started == FALSE) { 142 428 ms_mutex_unlock(&d->mutex); 143 429 return; 430 } 431 if (d->bufferizer->size >= len) { 432 UInt32 bsize = d->writeBufferByteSize; 433 uint8_t *pData = ms_malloc(len); 434 435 ms_bufferizer_read(d->bufferizer, pData, len); 436 err = AudioConverterConvertBuffer(d->writeAudioConverter, 437 len, 438 pData, 439 &bsize, inBuffer->mAudioData); 440 if (err != noErr) { 441 ms_error("writeCallback: AudioConverterConvertBuffer %d", err); 442 } 443 ms_free(pData); 444 445 if (bsize != d->writeBufferByteSize) 446 ms_warning("d->writeBufferByteSize = %i len = %i bsize = %i", 447 d->writeBufferByteSize, len, bsize); 144 448 } else { 145 449 memset(inBuffer->mAudioData, 0, d->writeBufferByteSize); 146 450 } 147 451 inBuffer->mAudioDataByteSize = d->writeBufferByteSize; 148 err = AudioQueueEnqueueBuffer ( 149 d->writeQueue, 150 inBuffer, 151 0, 152 NULL 153 ); 154 if(err != noErr) { 452 err = AudioQueueEnqueueBuffer(d->writeQueue, inBuffer, 0, NULL); 453 if (err != noErr) { 155 454 ms_error("AudioQueueEnqueueBuffer %d", err); 156 455 } 157 } 158 159 void putWriteAQ(void *aqData, 160 int queuenum) 161 { 162 ms_debug("putWriteAQ"); 163 AQData *d=(AQData*)aqData; 456 ms_mutex_unlock(&d->mutex); 457 } 458 459 void putWriteAQ(void *aqData, int queuenum) 460 { 461 AQData *d = (AQData *) aqData; 164 462 OSStatus err; 165 err = AudioQueueEnqueueBuffer ( 166 d->writeQueue, 167 d->writeBuffers[queuenum], 168 0, 169 NULL 170 ); 171 if(err != noErr) { 463 err = AudioQueueEnqueueBuffer(d->writeQueue, 464 d->writeBuffers[queuenum], 0, NULL); 465 if (err != noErr) { 172 466 ms_error("AudioQueueEnqueueBuffer %d", err); 173 467 } … … 178 472 */ 179 473 180 void setupWrite(MS SndCard *card) {181 ms_debug("setupWrite"); 182 AQData *d =(AQData*)card->data;474 void setupWrite(MSFilter * f) 475 { 476 AQData *d = (AQData *) f->data; 183 477 OSStatus err; 184 478 185 479 int bufferIndex; 186 187 for (bufferIndex = 0; bufferIndex < kNumberAudio DataBuffers; ++bufferIndex) {188 189 err = AudioQueueAllocateBuffer ( 190 d->writeQueue,191 d->writeBufferByteSize,192 &d->writeBuffers[bufferIndex]193 );194 if (err != noErr) {480 481 for (bufferIndex = 0; bufferIndex < kNumberAudioOutDataBuffers; 482 ++bufferIndex) { 483 484 err = AudioQueueAllocateBuffer(d->writeQueue, 485 d->writeBufferByteSize, 486 &d->writeBuffers[bufferIndex] 487 ); 488 if (err != noErr) { 195 489 ms_error("setupWrite:AudioQueueAllocateBuffer %d", err); 196 490 } … … 202 496 */ 203 497 204 void setupRead(MS SndCard *card) {205 ms_debug("setupRead"); 206 AQData *d =(AQData*)card->data;498 void setupRead(MSFilter * f) 499 { 500 AQData *d = (AQData *) f->data; 207 501 OSStatus err; 208 502 … … 210 504 int bufferIndex; 211 505 212 for (bufferIndex = 0; bufferIndex < kNumberAudioDataBuffers; ++bufferIndex) { 213 506 for (bufferIndex = 0; bufferIndex < kNumberAudioInDataBuffers; 507 ++bufferIndex) { 508 214 509 AudioQueueBufferRef buffer; 215 216 err = AudioQueueAllocateBuffer ( 217 d->readQueue, 218 d->readBufferByteSize, 219 &buffer 220 ); 221 if(err != noErr) { 510 511 err = AudioQueueAllocateBuffer(d->readQueue, 512 d->readBufferByteSize, &buffer); 513 if (err != noErr) { 222 514 ms_error("setupRead:AudioQueueAllocateBuffer %d", err); 223 515 } 224 225 err = AudioQueueEnqueueBuffer ( 226 d->readQueue, 227 buffer, 228 0, 229 NULL 230 ); 231 if(err != noErr) { 516 517 err = AudioQueueEnqueueBuffer(d->readQueue, buffer, 0, NULL); 518 if (err != noErr) { 232 519 ms_error("AudioQueueEnqueueBuffer %d", err); 233 520 } … … 235 522 } 236 523 237 /* 238 mediastreamer2 function 239 */ 240 241 static void aq_set_level(MSSndCard *card, MSSndCardMixerElem e, int percent) 242 { 243 } 244 245 static int aq_get_level(MSSndCard *card, MSSndCardMixerElem e) 246 { 247 return 0; 248 } 249 250 static void aq_set_source(MSSndCard *card, MSSndCardCapture source) 251 { 252 } 253 254 static void aq_init(MSSndCard *card){ 255 ms_debug("aq_init"); 256 AQData *d=ms_new(AQData,1); 257 258 d->bits=16; 259 d->rate=8000; 260 d->stereo=FALSE; 261 262 d->read_started=FALSE; 263 d->write_started=FALSE; 524 525 static void aq_start_r(MSFilter * f) 526 { 527 AQData *d = (AQData *) f->data; 528 if (d->read_started == FALSE) { 529 OSStatus aqresult; 530 531 d->readAudioFormat.mSampleRate = d->rate; 532 d->readAudioFormat.mFormatID = kAudioFormatLinearPCM; 533 d->readAudioFormat.mFormatFlags = 534 kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 535 d->readAudioFormat.mFramesPerPacket = 1; 536 d->readAudioFormat.mChannelsPerFrame = 1; 537 d->readAudioFormat.mBitsPerChannel = d->bits; 538 d->readAudioFormat.mBytesPerPacket = d->bits / 8; 539 d->readAudioFormat.mBytesPerFrame = d->bits / 8; 540 541 //show_format("input device", &d->devicereadFormat); 542 //show_format("data from input filter", &d->readAudioFormat); 543 544 memcpy(&d->devicereadFormat, &d->readAudioFormat, 545 sizeof(d->readAudioFormat)); 546 d->readBufferByteSize = 547 kSecondsPerBuffer * d->devicereadFormat.mSampleRate * 548 (d->devicereadFormat.mBitsPerChannel / 8) * 549 d->devicereadFormat.mChannelsPerFrame; 550 551 aqresult = AudioConverterNew(&d->devicereadFormat, 552 &d->readAudioFormat, 553 &d->readAudioConverter); 554 if (aqresult != noErr) { 555 ms_error("d->readAudioConverter = %d", aqresult); 556 d->readAudioConverter = NULL; 557 } 558 559 aqresult = AudioQueueNewInput(&d->devicereadFormat, readCallback, d, // userData 560 NULL, // run loop 561 NULL, // run loop mode 562 0, // flags 563 &d->readQueue); 564 if (aqresult != noErr) { 565 ms_error("AudioQueueNewInput = %d", aqresult); 566 } 567 568 char uidname[256]; 569 CFStringGetCString(d->uidname, uidname, 256, 570 CFStringGetSystemEncoding()); 571 ms_message("AQ: using uidname:%s", uidname); 572 aqresult = 573 AudioQueueSetProperty(d->readQueue, 574 kAudioQueueProperty_CurrentDevice, 575 &d->uidname, sizeof(CFStringRef)); 576 if (aqresult != noErr) { 577 ms_error 578 ("AudioQueueSetProperty on kAudioQueueProperty_CurrentDevice %d", 579 aqresult); 580 } 581 582 setupRead(f); 583 AudioQueueStart(d->readQueue, NULL // start time. NULL means ASAP. 584 ); 585 if (aqresult != noErr) { 586 ms_error("AudioQueueStart %d", aqresult); 587 } 588 d->read_started = TRUE; 589 } 590 } 591 592 static void aq_stop_r(MSFilter * f) 593 { 594 AQData *d = (AQData *) f->data; 595 596 if (d->read_started == TRUE) { 597 ms_mutex_lock(&d->mutex); 598 d->read_started = FALSE; /* avoid a deadlock related to buffer conversion in callback */ 599 ms_mutex_unlock(&d->mutex); 600 AudioConverterDispose(d->readAudioConverter); 601 AudioQueueStop(d->readQueue, true); 602 AudioQueueDispose(d->readQueue, true); 603 } 604 } 605 606 static void aq_start_w(MSFilter * f) 607 { 608 AQData *d = (AQData *) f->data; 609 if (d->write_started == FALSE) { 610 OSStatus aqresult; 611 612 d->writeAudioFormat.mSampleRate = d->rate; 613 d->writeAudioFormat.mFormatID = kAudioFormatLinearPCM; 614 d->writeAudioFormat.mFormatFlags = 615 kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 616 d->writeAudioFormat.mFramesPerPacket = 1; 617 d->writeAudioFormat.mChannelsPerFrame = 1; 618 d->writeAudioFormat.mBitsPerChannel = d->bits; 619 d->writeAudioFormat.mBytesPerPacket = d->bits / 8; 620 d->writeAudioFormat.mBytesPerFrame = d->bits / 8; 621 622 //show_format("data provided to output filter", &d->writeAudioFormat); 623 //show_format("output device", &d->devicewriteFormat); 624 625 memcpy(&d->devicewriteFormat, &d->writeAudioFormat, 626 sizeof(d->writeAudioFormat)); 627 d->writeBufferByteSize = 628 kSecondsPerBuffer * d->devicewriteFormat.mSampleRate * 629 (d->devicewriteFormat.mBitsPerChannel / 8) * 630 d->devicewriteFormat.mChannelsPerFrame; 631 632 aqresult = AudioConverterNew(&d->writeAudioFormat, 633 &d->devicewriteFormat, 634 &d->writeAudioConverter); 635 if (aqresult != noErr) { 636 ms_error("d->writeAudioConverter = %d", aqresult); 637 d->writeAudioConverter = NULL; 638 } 639 // create the playback audio queue object 640 aqresult = AudioQueueNewOutput(&d->devicewriteFormat, writeCallback, d, NULL, /*CFRunLoopGetCurrent () */ 641 NULL, /*kCFRunLoopCommonModes */ 642 0, // run loop flags 643 &d->writeQueue); 644 if (aqresult != noErr) { 645 ms_error("AudioQueueNewOutput = %d", aqresult); 646 } 647 648 char uidname[256]; 649 CFStringGetCString(d->uidname, uidname, 256, 650 CFStringGetSystemEncoding()); 651 ms_message("AQ: using uidname:%s", uidname); 652 aqresult = 653 AudioQueueSetProperty(d->writeQueue, 654 kAudioQueueProperty_CurrentDevice, 655 &d->uidname, sizeof(CFStringRef)); 656 if (aqresult != noErr) { 657 ms_error 658 ("AudioQueueSetProperty on kAudioQueueProperty_CurrentDevice %d", 659 aqresult); 660 } 661 setupWrite(f); 662 d->curWriteBuffer = 0; 663 } 664 } 665 666 static void aq_stop_w(MSFilter * f) 667 { 668 AQData *d = (AQData *) f->data; 669 if (d->write_started == TRUE) { 670 ms_mutex_lock(&d->mutex); 671 d->write_started = FALSE; /* avoid a deadlock related to buffer conversion in callback */ 672 ms_mutex_unlock(&d->mutex); 673 AudioConverterDispose(d->writeAudioConverter); 674 AudioQueueStop(d->writeQueue, true); 675 676 AudioQueueDispose(d->writeQueue, true); 677 } 678 } 679 680 static mblk_t *aq_get(MSFilter * f) 681 { 682 AQData *d = (AQData *) f->data; 683 mblk_t *m; 684 ms_mutex_lock(&d->mutex); 685 m = getq(&d->rq); 686 ms_mutex_unlock(&d->mutex); 687 return m; 688 } 689 690 static void aq_put(MSFilter * f, mblk_t * m) 691 { 692 AQData *d = (AQData *) f->data; 693 ms_mutex_lock(&d->mutex); 694 ms_bufferizer_put(d->bufferizer, m); 695 ms_mutex_unlock(&d->mutex); 696 697 int len = 698 (d->writeBufferByteSize * d->writeAudioFormat.mSampleRate / 1) / 699 d->devicewriteFormat.mSampleRate / 700 d->devicewriteFormat.mChannelsPerFrame; 701 if (d->write_started == FALSE && d->bufferizer->size >= len) { 702 AudioQueueBufferRef curbuf = d->writeBuffers[d->curWriteBuffer]; 703 OSStatus err; 704 UInt32 bsize = d->writeBufferByteSize; 705 uint8_t *pData = ms_malloc(len); 706 707 ms_bufferizer_read(d->bufferizer, pData, len); 708 err = AudioConverterConvertBuffer(d->writeAudioConverter, 709 len, 710 pData, 711 &bsize, curbuf->mAudioData); 712 if (err != noErr) { 713 ms_error("writeCallback: AudioConverterConvertBuffer %d", err); 714 } 715 ms_free(pData); 716 717 if (bsize != d->writeBufferByteSize) 718 ms_warning("d->writeBufferByteSize = %i len = %i bsize = %i", 719 d->writeBufferByteSize, len, bsize); 720 721 curbuf->mAudioDataByteSize = d->writeBufferByteSize; 722 putWriteAQ(d, d->curWriteBuffer); 723 ++d->curWriteBuffer; 724 } 725 if (d->write_started == FALSE 726 && d->curWriteBuffer == kNumberAudioOutDataBuffers - 1) { 727 OSStatus err; 728 err = AudioQueueStart(d->writeQueue, NULL // start time. NULL means ASAP. 729 ); 730 if (err != noErr) { 731 ms_error("AudioQueueStart %d", err); 732 } 733 d->write_started = TRUE; 734 } 735 } 736 737 static void aq_init(MSFilter * f) 738 { 739 AQData *d = ms_new(AQData, 1); 740 d->bits = 16; 741 d->rate = 8000; 742 d->stereo = FALSE; 743 744 d->read_started = FALSE; 745 d->write_started = FALSE; 264 746 qinit(&d->rq); 265 d->bufferizer=ms_bufferizer_new(); 266 ms_mutex_init(&d->mutex,NULL); 267 card->data=d; 268 } 269 270 static void aq_uninit(MSSndCard *card){ 271 AQData *d=(AQData*)card->data; 272 flushq(&d->rq,0); 747 d->bufferizer = ms_bufferizer_new(); 748 ms_mutex_init(&d->mutex, NULL); 749 f->data = d; 750 } 751 752 static void aq_uninit(MSFilter * f) 753 { 754 AQData *d = (AQData *) f->data; 755 flushq(&d->rq, 0); 273 756 ms_bufferizer_destroy(d->bufferizer); 274 757 ms_mutex_destroy(&d->mutex); 758 if (d->uidname != NULL) 759 CFRelease(d->uidname); 275 760 ms_free(d); 276 761 } 277 762 278 static void aq_detect(MSSndCardManager *m); 279 static MSSndCard *aq_duplicate(MSSndCard *obj); 280 281 MSSndCardDesc aq_card_desc={ 282 .driver_type="AQ", 283 .detect=aq_detect, 284 .init=aq_init, 285 .set_level=aq_set_level, 286 .get_level=aq_get_level, 287 .set_capture=aq_set_source, 288 .set_control=NULL, 289 .get_control=NULL, 290 .create_reader=ms_aq_read_new, 291 .create_writer=ms_aq_write_new, 292 .uninit=aq_uninit, 293 .duplicate=aq_duplicate 294 }; 295 296 static MSSndCard *aq_duplicate(MSSndCard *obj){ 297 MSSndCard *card=ms_snd_card_new(&aq_card_desc); 298 card->name=ms_strdup(obj->name); 299 return card; 300 } 301 302 static MSSndCard *aq_card_new(){ 303 MSSndCard *card=ms_snd_card_new(&aq_card_desc); 304 card->name=ms_strdup("Audio Queue"); 305 return card; 306 } 307 308 static void aq_detect(MSSndCardManager *m){ 309 ms_debug("aq_detect"); 310 311 #if defined(__AudioHardware_h__) 312 OSStatus err; 313 UInt32 count; 314 AudioDeviceID inDevice, outDevice; 315 char name[255]; 316 317 count = sizeof(inDevice); 318 err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, 319 &count, 320 &inDevice); 321 if (err) { 322 ms_error("get kAudioHardwarePropertyDefaultInputDevice error %x", err); 323 return; 324 } 325 326 count = sizeof(char) * 255; 327 AudioDeviceGetProperty(inDevice, 0, false, kAudioDevicePropertyDeviceName, &count, &name); 328 ms_debug("InputDevice name = %s",name); 329 330 count = sizeof(outDevice); 331 err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, 332 &count, 333 &outDevice); 334 335 if (err) { 336 ms_error("get kAudioHardwarePropertyDefaultOutputDevice error %d", err); 337 return; 338 } 339 340 count = sizeof(char) * 255; 341 AudioDeviceGetProperty(outDevice, 0, false, kAudioDevicePropertyDeviceName, &count, &name); 342 ms_debug("OutputDevice name = %s", name); 343 344 UInt32 deviceBufferSize; 345 AudioStreamBasicDescription deviceFormat; 346 count = sizeof(deviceBufferSize); 347 err = AudioDeviceGetProperty(outDevice, 348 0, 349 false, 350 kAudioDevicePropertyBufferSize, 351 &count, 352 &deviceBufferSize); 353 if (err != kAudioHardwareNoError) { 354 ms_error("get kAudioDevicePropertyBufferSize error %ld", err); 355 return; 356 } 357 ms_debug("deviceBufferSize = %d", deviceBufferSize); 358 count = sizeof(deviceFormat); 359 err = AudioDeviceGetProperty(outDevice, 360 0, 361 false, 362 kAudioDevicePropertyStreamFormat, 363 &count, 364 &deviceFormat); 365 if (err != kAudioHardwareNoError) { 366 ms_error("get kAudioDevicePropertyStreamFormat error %ld", err); 367 return; 368 } 369 ms_debug("mSampleRate = %g", deviceFormat.mSampleRate); 370 ms_debug("mFormatFlags = %08lX", deviceFormat.mFormatFlags); 371 ms_debug("mBytesPerPacket = %ld", deviceFormat.mBytesPerPacket); 372 ms_debug("mFramesPerPacket = %ld", deviceFormat.mFramesPerPacket); 373 ms_debug("mChannelsPerFrame = %ld", deviceFormat.mChannelsPerFrame); 374 ms_debug("mBytesPerFrame = %ld", deviceFormat.mBytesPerFrame); 375 ms_debug("mBitsPerChannel = %ld", deviceFormat.mBitsPerChannel); 376 377 count = sizeof(deviceBufferSize); 378 err = AudioDeviceGetProperty(outDevice, 379 0, 380 false, 381 kAudioDevicePropertyBufferSize, 382 &count, 383 &deviceBufferSize); 384 if (err != kAudioHardwareNoError) { 385 ms_error("get kAudioDevicePropertyBufferSize error %ld", err); 386 return; 387 } 388 ms_debug("deviceBufferSize = %d", deviceBufferSize); 389 #endif 390 391 MSSndCard *card=aq_card_new(); 392 ms_snd_card_manager_add_card(m,card); 393 } 394 395 static void aq_start_r(MSSndCard *card){ 396 AQData *d=(AQData*)card->data; 397 ms_debug("aq_start_r"); 398 if(d->read_started == FALSE) { 399 OSStatus aqresult; 400 d->readBufferByteSize = kSecondsPerBuffer * d->rate * (d->bits / 8); 401 402 d->readAudioFormat.mSampleRate = d->rate; 403 d->readAudioFormat.mFormatID = kAudioFormatLinearPCM; 404 d->readAudioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 405 d->readAudioFormat.mFramesPerPacket = 1; 406 d->readAudioFormat.mChannelsPerFrame = 1; 407 d->readAudioFormat.mBitsPerChannel = d->bits; 408 d->readAudioFormat.mBytesPerPacket = d->bits / 8; 409 d->readAudioFormat.mBytesPerFrame = d->bits / 8; 410 411 aqresult = AudioQueueNewInput ( 412 &d->readAudioFormat, 413 readCallback, 414 d, // userData 415 NULL, // run loop 416 NULL, // run loop mode 417 0, // flags 418 &d->readQueue 419 ); 420 421 ms_debug("AudioQueueNewInput = %d", aqresult); 422 423 setupRead(card); 424 AudioQueueStart ( 425 d->readQueue, 426 NULL // start time. NULL means ASAP. 427 ); 428 d->read_started = TRUE; 429 } 430 } 431 432 static void aq_stop_r(MSSndCard *card){ 433 AQData *d=(AQData*)card->data; 434 435 if(d->read_started == TRUE) { 436 AudioQueueStop ( 437 d->readQueue, 438 true 439 ); 440 AudioQueueDispose(d->readQueue,true); 441 d->read_started=FALSE; 442 } 443 } 444 445 static void aq_start_w(MSSndCard *card){ 446 ms_debug("aq_start_w"); 447 AQData *d=(AQData*)card->data; 448 if(d->write_started == FALSE) { 449 OSStatus aqresult; 450 d->writeBufferByteSize = kSecondsPerBuffer * d->rate * (d->bits / 8); 451 452 d->writeAudioFormat.mSampleRate = d->rate; 453 d->writeAudioFormat.mFormatID = kAudioFormatLinearPCM; 454 d->writeAudioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 455 d->writeAudioFormat.mFramesPerPacket = 1; 456 d->writeAudioFormat.mChannelsPerFrame = 1; 457 d->writeAudioFormat.mBitsPerChannel = d->bits; 458 d->writeAudioFormat.mBytesPerPacket = d->bits / 8; 459 d->writeAudioFormat.mBytesPerFrame = d->bits / 8; 460 461 // create the playback audio queue object 462 aqresult = AudioQueueNewOutput ( 463 &d->writeAudioFormat, 464 writeCallback, 465 d, 466 NULL,/*CFRunLoopGetCurrent ()*/ 467 NULL,/*kCFRunLoopCommonModes*/ 468 0, // run loop flags 469 &d->writeQueue 470 ); 471 ms_debug("AudioQueueNewOutput = %d", aqresult); 472 473 setupWrite(card); 474 #if 0 475 AudioQueueStart ( 476 d->writeQueue, 477 NULL // start time. NULL means ASAP. 478 ); 479 d->write_started = TRUE; 480 #endif 481 d->curWriteBuffer = 0; 482 } 483 } 484 485 static void aq_stop_w(MSSndCard *card){ 486 AQData *d=(AQData*)card->data; 487 if(d->write_started == TRUE) { 488 AudioQueueStop ( 489 d->writeQueue, 490 true 491 ); 492 493 AudioQueueDispose(d->writeQueue,true); 494 d->write_started=FALSE; 495 } 496 } 497 498 static mblk_t *aq_get(MSSndCard *card){ 499 AQData *d=(AQData*)card->data; 763 static void aq_read_preprocess(MSFilter * f) 764 { 765 aq_start_r(f); 766 } 767 768 static void aq_read_postprocess(MSFilter * f) 769 { 770 aq_stop_r(f); 771 } 772 773 static void aq_read_process(MSFilter * f) 774 { 500 775 mblk_t *m; 501 ms_mutex_lock(&d->mutex); 502 m=getq(&d->rq); 503 ms_mutex_unlock(&d->mutex); 504 return m; 505 } 506 507 static void aq_put(MSSndCard *card, mblk_t *m){ 508 ms_debug("aq_put"); 509 AQData *d=(AQData*)card->data; 510 ms_mutex_lock(&d->mutex); 511 ms_bufferizer_put(d->bufferizer,m); 512 ms_mutex_unlock(&d->mutex); 513 514 if(d->write_started == FALSE && d->bufferizer->size >= d->writeBufferByteSize) { 515 AudioQueueBufferRef curbuf = d->writeBuffers[d->curWriteBuffer]; 516 if(ms_bufferizer_read(d->bufferizer, curbuf->mAudioData, d->writeBufferByteSize)) { 517 curbuf->mAudioDataByteSize = d->writeBufferByteSize; 518 putWriteAQ(d, d->curWriteBuffer); 519 ++d->curWriteBuffer; 520 } 521 } 522 if(d->write_started == FALSE && d->curWriteBuffer == kNumberAudioDataBuffers-1) { 523 OSStatus err; 524 err = AudioQueueStart ( 525 d->writeQueue, 526 NULL // start time. NULL means ASAP. 527 ); 528 ms_debug("AudioQueueStart %d", err); 529 d->write_started = TRUE; 530 } 531 } 532 533 static void aq_read_preprocess(MSFilter *f){ 534 MSSndCard *card=(MSSndCard*)f->data; 535 aq_start_r(card); 536 } 537 538 static void aq_read_postprocess(MSFilter *f){ 539 MSSndCard *card=(MSSndCard*)f->data; 540 aq_stop_r(card); 541 } 542 543 static void aq_read_process(MSFilter *f){ 544 MSSndCard *card=(MSSndCard*)f->data; 776 while ((m = aq_get(f)) != NULL) { 777 ms_queue_put(f->outputs[0], m); 778 } 779 } 780 781 static void aq_write_preprocess(MSFilter * f) 782 { 783 aq_start_w(f); 784 } 785 786 static void aq_write_postprocess(MSFilter * f) 787 { 788 aq_stop_w(f); 789 } 790 791 static void aq_write_process(MSFilter * f) 792 { 545 793 mblk_t *m; 546 while((m=aq_get(card))!=NULL){ 547 ms_queue_put(f->outputs[0],m); 548 } 549 } 550 551 static void aq_write_preprocess(MSFilter *f){ 552 ms_debug("aq_write_preprocess"); 553 MSSndCard *card=(MSSndCard*)f->data; 554 aq_start_w(card); 555 } 556 557 static void aq_write_postprocess(MSFilter *f){ 558 ms_debug("aq_write_postprocess"); 559 MSSndCard *card=(MSSndCard*)f->data; 560 aq_stop_w(card); 561 } 562 563 static void aq_write_process(MSFilter *f){ 564 // ms_debug("aq_write_process"); 565 MSSndCard *card=(MSSndCard*)f->data; 566 mblk_t *m; 567 while((m=ms_queue_get(f->inputs[0]))!=NULL){ 568 aq_put(card,m); 569 } 570 } 571 572 static int set_rate(MSFilter *f, void *arg){ 573 ms_debug("set_rate %d", *((int*)arg)); 574 MSSndCard *card=(MSSndCard*)f->data; 575 AQData *d=(AQData*)card->data; 576 d->rate=*((int*)arg); 794 while ((m = ms_queue_get(f->inputs[0])) != NULL) { 795 aq_put(f, m); 796 } 797 } 798 799 static int set_rate(MSFilter * f, void *arg) 800 { 801 AQData *d = (AQData *) f->data; 802 d->rate = *((int *) arg); 577 803 return 0; 578 804 } 805 806 static int read_get_rate(MSFilter * f, void *arg) 807 { 808 AQData *d = (AQData *) f->data; 809 *((int *) arg) = d->rate; 810 return 0; 811 } 812 813 static int write_get_rate(MSFilter * f, void *arg) 814 { 815 AQData *d = (AQData *) f->data; 816 *((int *) arg) = d->rate; 817 return 0; 818 } 819 579 820 /* 580 821 static int set_nchannels(MSFilter *f, void *arg){ 581 ms_debug("set_nchannels %d", *((int*)arg)); 582 MSSndCard *card=(MSSndCard*)f->data; 583 AQData *d=(AQData*)card->data; 822 AQData *d=(AQData*)f->data; 584 823 d->stereo=(*((int*)arg)==2); 585 824 return 0; 586 825 } 587 826 */ 588 static MSFilterMethod aq_methods[]={ 589 { MS_FILTER_SET_SAMPLE_RATE , set_rate }, 827 828 static MSFilterMethod aq_read_methods[] = { 829 {MS_FILTER_SET_SAMPLE_RATE, set_rate}, 830 {MS_FILTER_GET_SAMPLE_RATE, read_get_rate}, 590 831 /* not support yet 591 832 { MS_FILTER_SET_NCHANNELS , set_nchannels }, 592 833 */ 593 { 0 , NULL}834 {0, NULL} 594 835 }; 595 836 596 MSFilterDesc aq_read_desc={ 597 .id=MS_AQ_READ_ID, 598 .name="MSAQRead", 599 .text=N_("Sound capture filter for MacOS X Audio Queue Service"), 600 .category=MS_FILTER_OTHER, 601 .ninputs=0, 602 .noutputs=1, 603 .preprocess=aq_read_preprocess, 604 .process=aq_read_process, 605 .postprocess=aq_read_postprocess, 606 .methods=aq_methods 837 MSFilterDesc aq_read_desc = { 838 .id = MS_AQ_READ_ID, 839 .name = "MSAQRead", 840 .text = N_("Sound capture filter for MacOS X Audio Queue Service"), 841 .category = MS_FILTER_OTHER, 842 .ninputs = 0, 843 .noutputs = 1, 844 .init = aq_init, 845 .preprocess = aq_read_preprocess, 846 .process = aq_read_process, 847 .postprocess = aq_read_postprocess, 848 .uninit = aq_uninit, 849 .methods = aq_read_methods 607 850 }; 608 851 609 610 MSFilterDesc aq_write_desc={ 611 .id=MS_AQ_WRITE_ID, 612 .name="MSAQWrite", 613 .text=N_("Sound playback filter for MacOS X Audio Queue Service"), 614 .category=MS_FILTER_OTHER, 615 .ninputs=1, 616 .noutputs=0, 617 .preprocess=aq_write_preprocess, 618 .process=aq_write_process, 619 .postprocess=aq_write_postprocess, 620 .methods=aq_methods 852 static MSFilterMethod aq_write_methods[] = { 853 {MS_FILTER_SET_SAMPLE_RATE, set_rate}, 854 {MS_FILTER_GET_SAMPLE_RATE, write_get_rate}, 855 /* not support yet 856 { MS_FILTER_SET_NCHANNELS , set_nchannels }, 857 */ 858 {0, NULL} 621 859 }; 622 860 623 MSFilter *ms_aq_read_new(MSSndCard *card){ 624 ms_debug("ms_aq_read_new"); 625 MSFilter *f=ms_filter_new_from_desc(&aq_read_desc); 626 f->data=card; 861 MSFilterDesc aq_write_desc = { 862 .id = MS_AQ_WRITE_ID, 863 .name = "MSAQWrite", 864 .text = N_("Sound playback filter for MacOS X Audio Queue Service"), 865 .category = MS_FILTER_OTHER, 866 .ninputs = 1, 867 .noutputs = 0, 868 .init = aq_init, 869 .preprocess = aq_write_preprocess, 870 .process = aq_write_process, 871 .postprocess = aq_write_postprocess, 872 .uninit = aq_uninit, 873 .methods = aq_write_methods 874 }; 875 876 MSFilter *ms_aq_read_new(MSSndCard * card) 877 { 878 MSFilter *f = ms_filter_new_from_desc(&aq_read_desc); 879 AqSndDsCard *wc = (AqSndDsCard *) card->data; 880 AQData *d = (AQData *) f->data; 881 d->uidname = CFStringCreateCopy(NULL, wc->uidname); 882 memcpy(&d->devicereadFormat, &wc->devicereadFormat, 883 sizeof(AudioStreamBasicDescription)); 884 memcpy(&d->devicewriteFormat, &wc->devicewriteFormat, 885 sizeof(AudioStreamBasicDescription)); 627 886 return f; 628 887 } 629 888 630 889 631 MSFilter *ms_aq_write_new(MSSndCard *card){ 632 ms_debug("ms_aq_write_new"); 633 MSFilter *f=ms_filter_new_from_desc(&aq_write_desc); 634 f->data=card; 890 MSFilter *ms_aq_write_new(MSSndCard * card) 891 { 892 MSFilter *f = ms_filter_new_from_desc(&aq_write_desc); 893 AqSndDsCard *wc = (AqSndDsCard *) card->data; 894 AQData *d = (AQData *) f->data; 895 d->uidname = CFStringCreateCopy(NULL, wc->uidname); 896 memcpy(&d->devicereadFormat, &wc->devicereadFormat, 897 sizeof(AudioStreamBasicDescription)); 898 memcpy(&d->devicewriteFormat, &wc->devicewriteFormat, 899 sizeof(AudioStreamBasicDescription)); 635 900 return f; 636 901 }
Note: See TracChangeset
for help on using the changeset viewer.
