Changeset 89167 in vbox for trunk/src/VBox
- Timestamp:
- May 19, 2021 1:28:39 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp
r89165 r89167 45 45 #include <iprt/circbuf.h> 46 46 #include <iprt/mem.h> 47 48 47 #include <iprt/uuid.h> 49 48 #include <iprt/timer.h> … … 51 50 #include <CoreAudio/CoreAudio.h> 52 51 #include <CoreServices/CoreServices.h> 52 #include <AudioToolbox/AudioQueue.h> 53 53 #include <AudioUnit/AudioUnit.h> 54 #include <AudioToolbox/AudioConverter.h>55 #include <AudioToolbox/AudioToolbox.h>56 54 57 55 … … 72 70 # define CORE_AUDIO_WITH_BREAKPOINT_TIMER 73 71 #endif 74 75 /* Enables utilizing the Core Audio converter unit for converting76 * input / output from/to our requested formats. That might be more77 * performant than using our own routines later down the road. */78 /** @todo Needs more investigation and testing first before enabling. */79 //# define VBOX_WITH_AUDIO_CA_CONVERTER80 72 81 73 … … 130 122 131 123 132 #ifdef VBOX_WITH_AUDIO_CA_CONVERTER133 /**134 * Context data for the audio format converter.135 */136 typedef struct COREAUDIOCONVCBCTX137 {138 /** Pointer to the stream this context is bound to. */139 PCOREAUDIOSTREAM pStream; /**< @todo r=bird: It's part of the COREAUDIOSTREAM structure! You don't need this. */140 /** Source stream description. */141 AudioStreamBasicDescription asbdSrc;142 /** Destination stream description. */143 AudioStreamBasicDescription asbdDst;144 /** Pointer to native buffer list used for rendering the source audio data into. */145 AudioBufferList *pBufLstSrc;146 /** Total packet conversion count. */147 UInt32 uPacketCnt;148 /** Current packet conversion index. */149 UInt32 uPacketIdx;150 /** Error count, for limiting the logging. */151 UInt32 cErrors;152 } COREAUDIOCONVCBCTX;153 /** Pointer to the context of a conversion callback. */154 typedef COREAUDIOCONVCBCTX *PCOREAUDIOCONVCBCTX;155 #endif /* VBOX_WITH_AUDIO_CA_CONVERTER */156 157 124 /** 158 125 * Core audio buffer tracker. … … 187 154 /** The stream's acquired configuration. */ 188 155 PDMAUDIOSTREAMCFG Cfg; 189 /** Direction specific data. */190 union191 {192 struct193 {194 #if 0 /* Unused */195 /** The ratio between the device & the stream sample rate. */196 Float64 sampleRatio;197 #endif198 #ifdef VBOX_WITH_AUDIO_CA_CONVERTER199 /** The audio converter if necessary. NULL if no converter is being used. */200 AudioConverterRef ConverterRef;201 /** Callback context for the audio converter. */202 COREAUDIOCONVCBCTX convCbCtx;203 #endif204 } In;205 //struct {} Out;206 };207 156 /** List node for the device's stream list. */ 208 157 RTLISTNODE Node; … … 316 265 317 266 /********************************************************************************************************************************* 318 * Global Variables *319 *********************************************************************************************************************************/320 #ifdef VBOX_WITH_AUDIO_CA_CONVERTER321 /** Error code which indicates "End of data" */322 static const OSStatus g_rcCoreAudioConverterEOFDErr = 0x656F6664; /* 'eofd' */323 #endif324 325 326 /*********************************************************************************************************************************327 267 * Internal Functions * 328 268 *********************************************************************************************************************************/ … … 493 433 } 494 434 #endif /* unused */ 495 496 497 #ifdef VBOX_WITH_AUDIO_CA_CONVERTER498 499 /**500 * Initializes a conversion callback context.501 *502 * @return IPRT status code.503 * @param pConvCbCtx Conversion callback context to initialize.504 * @param pStream Pointer to stream to use.505 * @param pASBDSrc Input (source) stream description to use.506 * @param pASBDDst Output (destination) stream description to use.507 */508 static int drvHostAudioCaInitConvCbCtx(PCOREAUDIOCONVCBCTX pConvCbCtx, PCOREAUDIOSTREAM pStream,509 AudioStreamBasicDescription *pASBDSrc, AudioStreamBasicDescription *pASBDDst)510 {511 AssertPtrReturn(pConvCbCtx, VERR_INVALID_POINTER);512 AssertPtrReturn(pStream, VERR_INVALID_POINTER);513 AssertPtrReturn(pASBDSrc, VERR_INVALID_POINTER);514 AssertPtrReturn(pASBDDst, VERR_INVALID_POINTER);515 516 # ifdef DEBUG517 drvHostAudioCaPrintASBD("CbCtx: Src", pASBDSrc);518 drvHostAudioCaPrintASBD("CbCtx: Dst", pASBDDst);519 # endif520 521 pConvCbCtx->pStream = pStream;522 523 memcpy(&pConvCbCtx->asbdSrc, pASBDSrc, sizeof(AudioStreamBasicDescription));524 memcpy(&pConvCbCtx->asbdDst, pASBDDst, sizeof(AudioStreamBasicDescription));525 526 pConvCbCtx->pBufLstSrc = NULL;527 pConvCbCtx->cErrors = 0;528 529 return VINF_SUCCESS;530 }531 532 533 /**534 * Uninitializes a conversion callback context.535 *536 * @return IPRT status code.537 * @param pConvCbCtx Conversion callback context to uninitialize.538 */539 static void drvHostAudioCaUninitConvCbCtx(PCOREAUDIOCONVCBCTX pConvCbCtx)540 {541 AssertPtrReturnVoid(pConvCbCtx);542 543 pConvCbCtx->pStream = NULL;544 545 RT_ZERO(pConvCbCtx->asbdSrc);546 RT_ZERO(pConvCbCtx->asbdDst);547 548 pConvCbCtx->pBufLstSrc = NULL;549 pConvCbCtx->cErrors = 0;550 }551 552 /* Callback to convert audio input data from one format to another. */553 static OSStatus drvHostAudioCaConverterCb(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets,554 AudioBufferList *ioData, AudioStreamPacketDescription **ppASPD, void *pvUser)555 {556 RT_NOREF(inAudioConverter);557 558 AssertPtrReturn(ioNumberDataPackets, g_rcCoreAudioConverterEOFDErr);559 AssertPtrReturn(ioData, g_rcCoreAudioConverterEOFDErr);560 561 PCOREAUDIOCONVCBCTX pConvCbCtx = (PCOREAUDIOCONVCBCTX)pvUser;562 AssertPtr(pConvCbCtx);563 564 /* Initialize values. */565 ioData->mBuffers[0].mNumberChannels = 0;566 ioData->mBuffers[0].mDataByteSize = 0;567 ioData->mBuffers[0].mData = NULL;568 569 if (ppASPD)570 {571 Log3Func(("Handling packet description not implemented\n"));572 }573 else574 {575 /** @todo Check converter ID? */576 577 /** @todo Handled non-interleaved data by going through the full buffer list,578 * not only through the first buffer like we do now. */579 Log3Func(("ioNumberDataPackets=%RU32\n", *ioNumberDataPackets));580 581 UInt32 cNumberDataPackets = *ioNumberDataPackets;582 Assert(pConvCbCtx->uPacketIdx + cNumberDataPackets <= pConvCbCtx->uPacketCnt);583 584 if (cNumberDataPackets)585 {586 AssertPtr(pConvCbCtx->pBufLstSrc);587 Assert(pConvCbCtx->pBufLstSrc->mNumberBuffers == 1); /* Only one buffer for the source supported atm. */588 589 AudioStreamBasicDescription *pSrcASBD = &pConvCbCtx->asbdSrc;590 AudioBuffer *pSrcBuf = &pConvCbCtx->pBufLstSrc->mBuffers[0];591 592 size_t cbOff = pConvCbCtx->uPacketIdx * pSrcASBD->mBytesPerPacket;593 594 cNumberDataPackets = RT_MIN((pSrcBuf->mDataByteSize - cbOff) / pSrcASBD->mBytesPerPacket,595 cNumberDataPackets);596 597 void *pvAvail = (uint8_t *)pSrcBuf->mData + cbOff;598 size_t cbAvail = RT_MIN(pSrcBuf->mDataByteSize - cbOff, cNumberDataPackets * pSrcASBD->mBytesPerPacket);599 600 Log3Func(("cNumberDataPackets=%RU32, cbOff=%zu, cbAvail=%zu\n", cNumberDataPackets, cbOff, cbAvail));601 602 /* Set input data for the converter to use.603 * Note: For VBR (Variable Bit Rates) or interleaved data handling we need multiple buffers here. */604 ioData->mNumberBuffers = 1;605 606 ioData->mBuffers[0].mNumberChannels = pSrcBuf->mNumberChannels;607 ioData->mBuffers[0].mDataByteSize = cbAvail;608 ioData->mBuffers[0].mData = pvAvail;609 610 # ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA611 RTFILE fh;612 int rc = RTFileOpen(&fh,VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH "caConverterCbInput.pcm",613 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);614 if (RT_SUCCESS(rc))615 {616 RTFileWrite(fh, pvAvail, cbAvail, NULL);617 RTFileClose(fh);618 }619 else620 AssertFailed();621 # endif622 pConvCbCtx->uPacketIdx += cNumberDataPackets;623 Assert(pConvCbCtx->uPacketIdx <= pConvCbCtx->uPacketCnt);624 625 *ioNumberDataPackets = cNumberDataPackets;626 }627 }628 629 Log3Func(("%RU32 / %RU32 -> ioNumberDataPackets=%RU32\n",630 pConvCbCtx->uPacketIdx, pConvCbCtx->uPacketCnt, *ioNumberDataPackets));631 632 return noErr;633 }634 635 #endif /* VBOX_WITH_AUDIO_CA_CONVERTER */636 435 637 436 … … 2833 2632 #ifdef CORE_AUDIO_WITH_BREAKPOINT_TIMER 2834 2633 pThis->hBreakpointTimer = NIL_RTTIMERLR; 2835 #endif 2634 #endif 2836 2635 PDMAudioHostEnumInit(&pThis->Devices); 2837 2636 /* IBase */
Note:
See TracChangeset
for help on using the changeset viewer.