Changeset 50680 in vbox for trunk/src/VBox/Devices/Audio/DrvAudio.c
- Timestamp:
- Mar 4, 2014 4:26:34 PM (11 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvAudio.c
r49765 r50680 1 /* $Id$ */ 2 /** @file 3 * Intermedia audio driver.. 4 * 5 * @remarks Intermediate audio driver having audio device as one of the sink and 6 * host backend as other.. 7 */ 8 1 9 /* 10 * Copyright (C) 2006-2014 Oracle Corporation 11 * 12 * This file is part of VirtualBox Open Source Edition (OSE), as 13 * available from http://www.virtualbox.org. This file is free software; 14 * you can redistribute it and/or modify it under the terms of the GNU 15 * General Public License (GPL) as published by the Free Software 16 * Foundation, in version 2 as it comes in the "COPYING" file of the 17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 18 * hope that it will be1 useful, but WITHOUT ANY WARRANTY of any kind. 19 * -------------------------------------------------------------------- 20 * 21 * This code is based on: audio.c from QEMU AUDIO subsystem. 22 * 2 23 * QEMU Audio subsystem 3 24 * … … 22 43 * THE SOFTWARE. 23 44 */ 45 46 24 47 #define LOG_GROUP LOG_GROUP_DEV_AUDIO 25 48 #include <VBox/vmm/pdm.h> 26 49 #include <VBox/err.h> 27 50 #include <VBox/vmm/mm.h> 51 #include <VBox/vmm/pdmaudioifs.h> 28 52 29 53 #include <VBox/log.h> … … 41 65 42 66 #define AUDIO_CAP "audio" 43 #include "audio.h" 44 #include "audio_int.h" 67 #include "DrvAudio.h" 45 68 46 69 #ifdef RT_OS_WINDOWS 47 70 #define strcasecmp stricmp 48 71 #endif 49 50 /* #define DEBUG_PLIVE */51 /* #define DEBUG_LIVE */52 /* #define DEBUG_OUT */53 /* #define DEBUG_CAPTURE */54 55 #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"56 57 /**58 * @implements PDMIAUDIOCONNECTOR59 */60 typedef struct DRVAUDIO61 {62 /** The audio interface. */63 PDMIAUDIOCONNECTOR IAudioConnector;64 /** Pointer to the driver instance. */65 PPDMDRVINS pDrvIns;66 } DRVAUDIO, *PDRVAUDIO;67 72 68 73 static struct audio_driver *drvtab[] = { … … 98 103 }; 99 104 105 extern t_sample *convAudio; 106 extern f_sample *clipAudio; 107 108 extern t_sample *convAudioIn; 109 extern f_sample *clipAudioIn; 100 110 static char *audio_streamname; 101 111 … … 104 114 return audio_streamname; 105 115 } 106 107 struct fixed_settings {108 int enabled;109 int nb_voices;110 int greedy;111 audsettings_t settings;112 };113 114 static struct {115 struct fixed_settings fixed_out;116 struct fixed_settings fixed_in;117 union {118 int hz;119 int64_t ticks;120 } period;121 int plive;122 } conf = {123 { /* DAC fixed settings */124 1, /* enabled */125 1, /* nb_voices */126 1, /* greedy */127 {128 44100, /* freq */129 2, /* nchannels */130 AUD_FMT_S16 /* fmt */131 }132 },133 134 { /* ADC fixed settings */135 1, /* enabled */136 1, /* nb_voices */137 1, /* greedy */138 {139 44100, /* freq */140 2, /* nchannels */141 AUD_FMT_S16 /* fmt */142 }143 },144 145 { 200 }, /* frequency (in Hz) */146 0, /* plive */147 };148 149 static AudioState glob_audio_state;150 116 151 117 volume_t nominal_volume = { … … 165 131 }; 166 132 167 #ifdef VBOX168 133 volume_t sum_out_volume = 169 134 { … … 190 155 INT_MAX 191 156 }; 192 #endif 157 158 159 /***************** ring buffer Hanlding section **************/ 160 static void IORingBufferCreate(PIORINGBUFFER *ppBuffer, uint32_t cSize) 161 { 162 PIORINGBUFFER pTmpBuffer; 163 164 AssertPtr(ppBuffer); 165 166 *ppBuffer = NULL; 167 pTmpBuffer = RTMemAllocZ(sizeof(IORINGBUFFER)); 168 if (pTmpBuffer) 169 { 170 pTmpBuffer->pBuffer = RTMemAlloc(cSize); 171 if(pTmpBuffer->pBuffer) 172 { 173 pTmpBuffer->cBufSize = cSize; 174 *ppBuffer = pTmpBuffer; 175 } 176 else 177 RTMemFree(pTmpBuffer); 178 } 179 } 180 181 static void IORingBufferDestroy(PIORINGBUFFER pBuffer) 182 { 183 if (pBuffer) 184 { 185 if (pBuffer->pBuffer) 186 RTMemFree(pBuffer->pBuffer); 187 RTMemFree(pBuffer); 188 } 189 } 190 191 DECL_FORCE_INLINE(void) IORingBufferReset(PIORINGBUFFER pBuffer) 192 { 193 AssertPtr(pBuffer); 194 195 pBuffer->uReadPos = 0; 196 pBuffer->uWritePos = 0; 197 pBuffer->cBufferUsed = 0; 198 } 199 200 DECL_FORCE_INLINE(uint32_t) IORingBufferFree(PIORINGBUFFER pBuffer) 201 { 202 AssertPtr(pBuffer); 203 return pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed); 204 } 205 206 DECL_FORCE_INLINE(uint32_t) IORingBufferUsed(PIORINGBUFFER pBuffer) 207 { 208 AssertPtr(pBuffer); 209 return ASMAtomicReadU32(&pBuffer->cBufferUsed); 210 } 211 212 DECL_FORCE_INLINE(uint32_t) IORingBufferSize(PIORINGBUFFER pBuffer) 213 { 214 AssertPtr(pBuffer); 215 return pBuffer->cBufSize; 216 } 217 218 static void IORingBufferAquireReadBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize) 219 { 220 uint32_t uUsed = 0; 221 uint32_t uSize = 0; 222 223 AssertPtr(pBuffer); 224 225 *ppStart = 0; 226 *pcSize = 0; 227 228 /* How much is in use? */ 229 uUsed = ASMAtomicReadU32(&pBuffer->cBufferUsed); 230 if (uUsed > 0) 231 { 232 /* Get the size out of the requested size, the read block till the end 233 * of the buffer & the currently used size. */ 234 uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uReadPos, uUsed)); 235 if (uSize > 0) 236 { 237 /* Return the pointer address which point to the current read 238 * position. */ 239 *ppStart = pBuffer->pBuffer + pBuffer->uReadPos; 240 *pcSize = uSize; 241 } 242 } 243 } 244 245 DECL_FORCE_INLINE(void) IORingBufferReleaseReadBlock(PIORINGBUFFER pBuffer, uint32_t cSize) 246 { 247 AssertPtr(pBuffer); 248 249 /* Split at the end of the buffer. */ 250 pBuffer->uReadPos = (pBuffer->uReadPos + cSize) % pBuffer->cBufSize; 251 ASMAtomicSubU32(&pBuffer->cBufferUsed, cSize); 252 } 253 254 static void IORingBufferAquireWriteBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize) 255 { 256 uint32_t uFree; 257 uint32_t uSize; 258 259 AssertPtr(pBuffer); 260 261 *ppStart = 0; 262 *pcSize = 0; 263 264 /* How much is free? */ 265 uFree = pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed); 266 if (uFree > 0) 267 { 268 /* Get the size out of the requested size, the write block till the end 269 * of the buffer & the currently free size. */ 270 uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uWritePos, uFree)); 271 if (uSize > 0) 272 { 273 /* Return the pointer address which point to the current write 274 * position. */ 275 *ppStart = pBuffer->pBuffer + pBuffer->uWritePos; 276 *pcSize = uSize; 277 } 278 } 279 } 280 281 DECL_FORCE_INLINE(void) IORingBufferReleaseWriteBlock(PIORINGBUFFER pBuffer, uint32_t cSize) 282 { 283 AssertPtr(pBuffer); 284 285 /* Split at the end of the buffer. */ 286 pBuffer->uWritePos = (pBuffer->uWritePos + cSize) % pBuffer->cBufSize; 287 288 ASMAtomicAddU32(&pBuffer->cBufferUsed, cSize); 289 } 290 291 /****************** Ring Buffer Function Ends *****************/ 193 292 194 293 /* http://www.df.lth.se/~john_e/gems/gem002d.html */ … … 203 302 return u; 204 303 } 205 206 304 uint32_t lsbindex (uint32_t u) 207 305 { 208 306 return popcount ((u&-u)-1); 209 307 } 210 211 308 uint64_t audio_get_clock (void) 212 309 { 213 AudioState *s; 214 215 s = &glob_audio_state; 216 return PDMDrvHlpTMGetVirtualTime (s->pDrvIns); 217 } 218 310 return PDMDrvHlpTMGetVirtualTime (gpDrvIns); 311 } 219 312 uint64_t audio_get_ticks_per_sec (void) 220 313 { 221 AudioState *s; 222 223 s = &glob_audio_state; 224 return PDMDrvHlpTMGetVirtualFreq (s->pDrvIns); 225 } 226 227 #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED 228 #error No its not 229 #else 230 int audio_bug (const char *funcname, int cond) 231 { 232 if (cond) { 233 static int shown; 234 235 AUD_log (NULL, "A bug was just triggered in %s\n", funcname); 236 if (!shown) { 237 shown = 1; 238 AUD_log (NULL, "Save all your work and restart without audio\n"); 239 AUD_log (NULL, "Please send a bug, see www.virtualbox.org\n"); 240 AUD_log (NULL, "I am sorry\n"); 241 } 242 AUD_log (NULL, "Context:\n"); 243 244 #if defined AUDIO_BREAKPOINT_ON_BUG 245 # if defined HOST_I386 246 # if defined __GNUC__ 247 __asm__ ("int3"); 248 # elif defined _MSC_VER 249 _asm _emit 0xcc; 250 # else 251 abort (); 252 # endif 253 # else 254 abort (); 255 # endif 256 #endif 257 } 258 259 return cond; 260 } 261 #endif 262 263 static inline int audio_bits_to_index (int bits) 314 return PDMDrvHlpTMGetVirtualFreq (gpDrvIns); 315 } 316 317 inline int audio_bits_to_index (int bits) 264 318 { 265 319 switch (bits) { … … 274 328 275 329 default: 276 audio_bug ("bits_to_index", 1); 277 AUD_log (NULL, "invalid bits %d\n", bits); 330 LogFlow(("invalid bits %d\n", bits)); 278 331 return 0; 279 332 } 280 }281 282 void *audio_calloc (const char *funcname, int nmemb, size_t size)283 {284 int cond;285 size_t len;286 287 len = nmemb * size;288 cond = !nmemb || !size;289 cond |= nmemb < 0;290 cond |= len < size;291 292 if (audio_bug ("audio_calloc", cond)) {293 AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",294 funcname);295 AUD_log (NULL, "nmemb=%d size=%" FMTZ "u (len=%" FMTZ "u)\n",296 nmemb, size, len);297 return NULL;298 }299 300 return qemu_mallocz (len);301 333 } 302 334 … … 323 355 } 324 356 325 dolog ("Bogus audfmt %d returning S16\n", fmt);357 LogFlow(("Bogus audfmt %d returning S16\n", fmt)); 326 358 return "S16"; 327 359 } 328 360 329 static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, 330 int *defaultp) 361 static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp) 331 362 { 332 363 if (!strcasecmp (s, "u8")) { … … 355 386 } 356 387 else { 357 dolog("Bogus audio format `%s' using %s\n",358 s, audio_audfmt_to_string (defval));388 LogFlow(("Bogus audio format `%s' using %s\n", 389 s, audio_audfmt_to_string (defval))); 359 390 *defaultp = 1; 360 391 return defval; … … 362 393 } 363 394 364 static audfmt_e audio_get_conf_fmt (PCFGMNODE pCfgHandle, const char *envname, 365 audfmt_e defval, 366 int *defaultp) 395 static audfmt_e drvAudioGetConfFormat(PCFGMNODE pCfgHandle, const char *envname, audfmt_e defval, int *defaultp) 367 396 { 368 397 char *var = NULL; … … 382 411 } 383 412 384 static int audio_get_conf_int (PCFGMNODEpCfgHandle, const char *key, int defval, int *defaultp)413 static int drvAudioGetConfInt(PCFGMNODE pCfgHandle, const char *key, int defval, int *defaultp) 385 414 { 386 415 int rc; … … 407 436 } 408 437 409 static const char *audio_get_conf_str (PCFGMNODE pCfgHandle, const char *key, 410 const char *defval, 411 int *defaultp) 438 static const char *drvAudioGetConfStr(PCFGMNODE pCfgHandle, const char *key, const char *defval, int *defaultp) 412 439 { 413 440 char *val = NULL; … … 429 456 } 430 457 431 void AUD_vlog (const char *cap, const char *fmt, va_list va) 432 { 433 va_list va2; 434 va_copy (va2, va); /* Have to make a copy here or GCC will break. */ 435 if (cap) { 436 Log (("%s: %N", cap, fmt, &va2)); 437 } 438 else { 439 Log (("%N", fmt, &va2)); 440 } 441 va_end (va2); 442 } 443 444 void AUD_log (const char *cap, const char *fmt, ...) 445 { 446 va_list va; 447 448 va_start (va, fmt); 449 AUD_vlog (cap, fmt, va); 450 va_end (va); 451 } 452 453 static void audio_process_options (PCFGMNODE pCfgHandle, const char *prefix, 454 struct audio_option *opt) 458 static void drvAudioProcessOptions(PCFGMNODE pCfgHandle, const char *prefix, struct audio_option *opt) 455 459 { 456 460 int def; … … 458 462 PCFGMNODE pCfgChildChildHandle = NULL; 459 463 460 if (audio_bug (AUDIO_FUNC, !prefix)) { 461 dolog ("prefix = NULL\n"); 462 return; 463 } 464 465 if (audio_bug (AUDIO_FUNC, !opt)) { 466 dolog ("opt = NULL\n"); 464 if (!prefix || !opt) 465 { 466 LogFlow(("prefix = NULL OR opt = NULL\n")); 467 467 return; 468 468 } … … 471 471 * The getter function will return default values. 472 472 */ 473 if(pCfgHandle != NULL) { 473 if(pCfgHandle != NULL) 474 { 474 475 /* If its audio general setting, need to traverse to one child node. 475 476 * /Devices/ichac97/0/LUN#0/Config/Audio … … 499 500 500 501 for (; opt->name; opt++) { 502 LogFlow(("Option value pointer for `%s' is not set\n", 503 opt->name)); 501 504 if (!opt->valp) { 502 dolog("Option value pointer for `%s' is not set\n",503 opt->name) ;505 LogFlow(("Option value pointer for `%s' is not set\n", 506 opt->name)); 504 507 continue; 505 508 } … … 510 513 { 511 514 int *intp = opt->valp; 512 *intp = audio_get_conf_int(pCfgHandle, opt->name, *intp, &def);515 *intp = drvAudioGetConfInt(pCfgHandle, opt->name, *intp, &def); 513 516 } 514 517 break; … … 517 520 { 518 521 audfmt_e *fmtp = opt->valp; 519 *fmtp = audio_get_conf_fmt(pCfgHandle, opt->name, *fmtp, &def);522 *fmtp = drvAudioGetConfFormat(pCfgHandle, opt->name, *fmtp, &def); 520 523 } 521 524 break; … … 524 527 { 525 528 const char **strp = opt->valp; 526 *strp = audio_get_conf_str(pCfgHandle, opt->name, *strp, &def);529 *strp = drvAudioGetConfStr(pCfgHandle, opt->name, *strp, &def); 527 530 } 528 531 break; 529 532 530 533 default: 531 dolog("Bad value tag for option `%s' - %d\n",532 opt->name, opt->tag) ;534 LogFlow(("Bad value tag for option `%s' - %d\n", 535 opt->name, opt->tag)); 533 536 break; 534 537 } … … 541 544 } 542 545 543 static void audio_print_settings(audsettings_t *as)544 { 545 dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);546 static void drvAudioPrintSettings(audsettings_t *as) 547 { 548 LogFlow(("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels)); 546 549 547 550 switch (as->fmt) { 548 551 case AUD_FMT_S8: 549 AUD_log (NULL, "S8");552 LogFlow(("S8\n")); 550 553 break; 551 554 case AUD_FMT_U8: 552 AUD_log (NULL, "U8");555 LogFlow(("U8\n")); 553 556 break; 554 557 case AUD_FMT_S16: 555 AUD_log (NULL, "S16");558 LogFlow(("S16\n")); 556 559 break; 557 560 case AUD_FMT_U16: 558 AUD_log (NULL, "U16");561 LogFlow(("U16\n")); 559 562 break; 560 563 case AUD_FMT_S32: 561 AUD_log (NULL, "S32");564 LogFlow(("S32\n")); 562 565 break; 563 566 case AUD_FMT_U32: 564 AUD_log (NULL, "U32");567 LogFlow(("U32\n")); 565 568 break; 566 569 default: 567 AUD_log (NULL, "invalid(%d)", as->fmt);570 LogFlow(("invalid(%d)\n", as->fmt)); 568 571 break; 569 572 } 570 573 571 AUD_log (NULL, " endianness="); 572 switch (as->endianness) { 574 LogFlow(("endianness=\n")); 575 switch (as->endianness) 576 { 573 577 case 0: 574 AUD_log (NULL, "little");578 LogFlow(("little\n")); 575 579 break; 576 580 case 1: 577 AUD_log (NULL, "big");581 LogFlow(("big\n")); 578 582 break; 579 583 default: 580 AUD_log (NULL, "invalid");584 LogFlow(("invalid\n")); 581 585 break; 582 586 } 583 AUD_log (NULL, "\n"); 584 } 585 586 static int audio_validate_settings (audsettings_t *as) 587 } 588 589 static int drvAudioValidateSettings(audsettings_t *as) 587 590 { 588 591 int invalid; … … 608 611 } 609 612 610 static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)613 int drvAudioPcmInfoEq(PDMPCMPROPERTIES * pProps, audsettings_t *as) 611 614 { 612 615 int bits = 8, sign = 0; … … 630 633 break; 631 634 } 632 return info->freq== as->freq633 && info->nchannels == as->nchannels634 && info->sign== sign635 && info->bits == bits636 && info->swap_endianness== (as->endianness != AUDIO_HOST_ENDIANNESS);637 } 638 639 void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as)635 return pProps->uFrequency == as->freq 636 && pProps->cChannels == as->nchannels 637 && pProps->fSigned == sign 638 && pProps->cBits == bits 639 && pProps->fSwapEndian == (as->endianness != AUDIO_HOST_ENDIANNESS); 640 } 641 642 void drvAudioPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as) 640 643 { 641 644 int bits = 8, sign = 0, shift = 0; … … 662 665 } 663 666 664 info->freq= as->freq;665 info->bits = bits;666 info->sign= sign;667 info->nchannels = as->nchannels;668 info->shift = (as->nchannels == 2) + shift;669 info->align = (1 << info->shift) - 1;670 info->bytes_per_second = info->freq << info->shift;671 info->swap_endianness= (as->endianness != AUDIO_HOST_ENDIANNESS);667 pProps->uFrequency = as->freq; 668 pProps->cBits = bits; 669 pProps->fSigned = sign; 670 pProps->cChannels = as->nchannels; 671 pProps->cShift = (as->nchannels == 2) + shift; 672 pProps->fAlign = (1 << pProps->cShift) - 1; 673 pProps->cbPerSec = pProps->uFrequency << pProps->cShift; 674 pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS); 672 675 } 673 676 … … 722 725 723 726 default: 724 AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n", 725 info->bits); 727 LogFlow(("audio_pcm_info_clear_buf: invalid bits %d\n", info->bits)); 726 728 break; 727 729 } … … 732 734 * Capture 733 735 */ 734 static void noop_conv (st_sample_t *dst, const void *src, 735 int samples, volume_t *vol) 736 static void noop_conv (st_sample_t *dst, const void *src, int samples, volume_t *vol) 736 737 { 737 738 (void) src; … … 741 742 } 742 743 743 static CaptureVoiceOut *audio_pcm_capture_find_specific (744 AudioState *s,745 audsettings_t *as746 )747 {748 CaptureVoiceOut *cap;749 750 for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {751 if (audio_pcm_info_eq (&cap->hw.info, as)) {752 return cap;753 }754 }755 return NULL;756 }757 758 static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)759 {760 struct capture_callback *cb;761 762 #ifdef DEBUG_CAPTURE763 dolog ("notification %d sent\n", cmd);764 #endif765 for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {766 cb->ops.notify (cb->opaque, cmd);767 }768 }769 770 744 static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled) 771 745 { 772 if (cap->hw.enabled != enabled) { 746 if (cap->hw.fEnabled != enabled) 747 { 773 748 audcnotification_e cmd; 774 cap->hw. enabled = enabled;749 cap->hw.fEnabled = enabled; 775 750 cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE; 776 audio_notify_capture (cap, cmd);777 778 } 779 780 static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap) 781 { 782 HWVoiceOut *hw = &cap->hw;783 SWVoiceOut *sw;751 } 752 } 753 754 static void drvAudioRecalcAndNotifyCapture(CaptureVoiceOut *cap) 755 { 756 PPDMHOSTVOICEOUT hw = &cap->hw; 757 PPDMGSTVOICEOUT sw; 758 PPDMGSTVOICEOUT pIter; 784 759 int enabled = 0; 785 786 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 787 if (sw->active) { 760 LogFlow(("drvAudioRecalcAndNotifyCaptuer \n")); 761 762 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 763 { 764 sw = pIter; 765 LogFlow(("1\n")); 766 if (sw->State.fActive) { 788 767 enabled = 1; 789 768 break; … … 793 772 } 794 773 795 static void audio_detach_capture (HWVoiceOut *hw) 796 { 797 SWVoiceCap *sc = hw->cap_head.lh_first; 798 799 while (sc) { 800 SWVoiceCap *sc1 = sc->entries.le_next; 801 SWVoiceOut *sw = &sc->sw; 774 void drvAudioDetachCapture(PPDMHOSTVOICEOUT pHostVoiceOut) 775 { 776 SWVoiceCap * sc; 777 SWVoiceCap *pIter; 778 LogFlow(("drvAudioDetachCapture \n")); 779 RTListForEach(&pHostVoiceOut->HeadCapturedVoice, pIter, SWVoiceCap, ListCapturedVoice) 780 { 781 sc = pIter; 782 PPDMGSTVOICEOUT sw = &sc->sw; 802 783 CaptureVoiceOut *cap = sc->cap; 803 int was_active = sw->active; 804 805 if (sw->rate) { 806 st_rate_stop (sw->rate); 807 sw->rate = NULL; 808 } 809 810 LIST_REMOVE (sw, entries); 811 LIST_REMOVE (sc, entries); 812 qemu_free (sc); 784 int was_active = sw->State.fActive; 785 786 if (sw->State.rate) { 787 st_rate_stop (sw->State.rate); 788 sw->State.rate = NULL; 789 } 790 791 while (!RTListIsEmpty(&sw->ListGstVoiceOut)) 792 { 793 PPDMGSTVOICEOUT pIterTmp = RTListGetFirst(&sw->ListGstVoiceOut, PDMGSTVOICEOUT, ListGstVoiceOut); 794 RTListNodeRemove(&pIterTmp->ListGstVoiceOut); 795 } 796 797 while (!RTListIsEmpty(&sc->ListCapturedVoice)) 798 { 799 SWVoiceCap * pIterTmp = RTListGetFirst(&sc->ListCapturedVoice, SWVoiceCap, ListCapturedVoice); 800 RTListNodeRemove(&pIterTmp->ListCapturedVoice); 801 } 802 813 803 if (was_active) { 814 804 /* We have removed soft voice from the capture: 815 805 this might have changed the overall status of the capture 816 806 since this might have been the only active voice */ 817 audio_recalc_and_notify_capture (cap); 818 } 819 sc = sc1; 820 } 821 } 822 823 static int audio_attach_capture (AudioState *s, HWVoiceOut *hw) 807 drvAudioRecalcAndNotifyCapture(cap); 808 } 809 } 810 } 811 812 int drvAudioAttachCapture(PDRVAUDIO pDrvAudio, PPDMHOSTVOICEOUT pHostVoiceOut) 824 813 { 825 814 CaptureVoiceOut *cap; 826 827 audio_detach_capture (hw); 828 for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) { 815 CaptureVoiceOut *pIter; 816 817 drvAudioDetachCapture(pHostVoiceOut); 818 RTListForEach(&pDrvAudio->HeadCapturedVoice, pIter, CaptureVoiceOut, ListCapturedVoice) 819 { 829 820 SWVoiceCap *sc; 830 SWVoiceOut *sw; 831 HWVoiceOut *hw_cap = &cap->hw; 832 833 sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc)); 834 if (!sc) { 835 dolog ("Could not allocate soft capture voice (%u bytes)\n", 836 sizeof (*sc)); 821 PPDMGSTVOICEOUT pGstVoiceOut; 822 cap = pIter; 823 PPDMHOSTVOICEOUT hw_cap = &cap->hw; 824 sc = (SWVoiceCap*) RTMemAllocZ(1 * sizeof (SWVoiceCap)); 825 if (!sc) 826 { 827 LogFlow(("Could not allocate soft capture voice (%u bytes)\n", 828 sizeof (*sc))); 837 829 return -1; 838 830 } 839 831 840 832 sc->cap = cap; 841 sw = &sc->sw; 842 sw->hw = hw_cap; 843 sw->info = hw->info; 844 sw->empty = 1; 845 sw->active = hw->enabled; 846 sw->conv = noop_conv; 847 sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq; 848 sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq); 849 if (!sw->rate) { 850 dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw)); 851 qemu_free (sw); 833 pGstVoiceOut = &sc->sw; 834 pGstVoiceOut->pHostVoiceOut = hw_cap; 835 pGstVoiceOut->Props = pHostVoiceOut->Props; 836 pGstVoiceOut->State.fEmpty = 1; 837 pGstVoiceOut->State.fActive = pHostVoiceOut->fEnabled; 838 LogFlow(("DrvAudio: setting gstvoiceout ratio. Freq=%d and Frew=%d", 839 hw_cap->Props.uFrequency, pGstVoiceOut->Props.uFrequency )); 840 pGstVoiceOut->State.ratio = ((int64_t) hw_cap->Props.uFrequency << 32) / pGstVoiceOut->Props.uFrequency; 841 pGstVoiceOut->State.rate = st_rate_start (pGstVoiceOut->Props.uFrequency, hw_cap->Props.uFrequency); 842 if (!pGstVoiceOut->State.rate) 843 { 844 LogFlow(("Error Could not start rate conversion \n")); 845 RTMemFree(pGstVoiceOut); 852 846 return -1; 853 847 } 854 LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries); 855 LIST_INSERT_HEAD (&hw->cap_head, sc, entries); 856 #ifdef DEBUG_CAPTURE 857 asprintf (&sw->name, "for %p %d,%d,%d", 858 hw, sw->info.freq, sw->info.bits, sw->info.nchannels); 859 dolog ("Added %s active = %d\n", sw->name, sw->active); 860 #endif 861 if (sw->active) { 848 RTListPrepend(&hw_cap->HeadGstVoiceOut, &pGstVoiceOut->ListGstVoiceOut); 849 RTListPrepend(&pHostVoiceOut->HeadCapturedVoice, &sc->ListCapturedVoice); 850 if (pGstVoiceOut->State.fActive) 851 { 862 852 audio_capture_maybe_changed (cap, 1); 863 853 } … … 869 859 * Hard voice (capture) 870 860 */ 871 static int audio_pcm_hw_find_min_in (HWVoiceIn *hw) 872 { 873 SWVoiceIn *sw; 874 int m = hw->total_samples_captured; 875 876 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 877 if (sw->active) { 878 m = audio_MIN (m, sw->total_hw_samples_acquired); 861 static int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw) 862 { 863 PPDMGSTVOICEIN pIter = NULL; 864 PPDMGSTVOICEIN pGstVoiceIn = NULL; 865 int m = hw->cSamplesCaptured; 866 867 RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn) 868 { 869 pGstVoiceIn = pIter; 870 LogFlow(("DrvAudio: pGstVioceIn = %p\n", pGstVoiceIn)); 871 if (pGstVoiceIn->State.fActive) 872 { 873 m = audio_MIN (m, pGstVoiceIn->cHostSamplesAcquired); 879 874 } 880 875 } … … 882 877 } 883 878 884 int audio_pcm_hw_get_live_in (HWVoiceIn *hw) 885 { 886 int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw); 887 if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) { 888 dolog ("live=%d hw->samples=%d\n", live, hw->samples); 879 int audio_pcm_hw_get_live_in (PPDMHOSTVOICEIN hw) 880 { 881 int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw); 882 if (live < 0 || live > hw->cSamples) 883 { 884 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 889 885 return 0; 890 886 } … … 895 891 * Soft voice (capture) 896 892 */ 897 static int audio_pcm_sw_get_rpos_in ( SWVoiceIn *sw)898 { 899 HWVoiceIn *hw = sw->hw;900 int live = hw-> total_samples_captured - sw->total_hw_samples_acquired;893 static int audio_pcm_sw_get_rpos_in (PPDMGSTVOICEIN sw) 894 { 895 PPDMHOSTVOICEIN hw = sw->hw; 896 int live = hw->cSamplesCaptured - sw->cHostSamplesAcquired; 901 897 int rpos; 902 898 903 if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) { 904 dolog ("live=%d hw->samples=%d\n", live, hw->samples); 899 if (live < 0 || live > hw->cSamples) 900 { 901 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 905 902 return 0; 906 903 } 907 904 908 rpos = hw-> wpos- live;905 rpos = hw->offWrite - live; 909 906 if (rpos >= 0) { 910 907 return rpos; 911 908 } 912 909 else { 913 return hw-> samples + rpos;914 } 915 } 916 917 int audio_pcm_sw_read ( SWVoiceIn *sw, void *buf, int size)918 { 919 HWVoiceIn *hw = sw->hw;910 return hw->cSamples + rpos; 911 } 912 } 913 914 int audio_pcm_sw_read (PDRVAUDIO pThis, PPDMGSTVOICEIN sw, PPDMHOSTSTEREOSAMPLE buf, int size) 915 { 916 PPDMHOSTVOICEIN hw = sw->hw; 920 917 int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0; 921 st_sample_t *src, *dst = sw->buf; 922 923 rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples; 924 925 live = hw->total_samples_captured - sw->total_hw_samples_acquired; 926 if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) { 927 dolog ("live_in=%d hw->samples=%d\n", live, hw->samples); 918 PPDMHOSTSTEREOSAMPLE src, dst = sw->buf; 919 PPDMHOSTSTEREOSAMPLE tmp = sw->buf; 920 PPDMHOSTSTEREOSAMPLE pSampleBuf; 921 char *pcDst = NULL; 922 char *pcSrc = NULL; 923 uint32_t cbToWrite; 924 uint32_t csAvail = 0; 925 uint32_t cSamplesRead = 0; 926 uint32_t cbToRead = 0; 927 uint32_t csWritten = 0; 928 uint32_t cSamplesInRingBuffer = 0; 929 uint32_t csToWrite; 930 uint32_t csLimit; 931 932 /* Max capacity to hold 1000 PDMHOSTSTERESAMPLE type samples. */ 933 pSampleBuf = (PPDMHOSTSTEREOSAMPLE) RTMemAlloc(1000 * sizeof(PDMHOSTSTEREOSAMPLE)); 934 rpos = audio_pcm_sw_get_rpos_in (sw) % hw->cSamples; 935 936 /* difference between how many samples have be captured/read by the host and how 937 * many have been transferred to guest (guest physical memory) to be utilized by the guest 938 * eg skype on guest or saving samples in file in guest. 939 */ 940 live = hw->cSamplesCaptured - sw->cHostSamplesAcquired; 941 if (live < 0 || live > hw->cSamples) 942 { 943 LogFlow(("Error: live_in=%d hw->samples=%d\n", live, hw->cSamples)); 928 944 return 0; 929 945 } 930 946 931 samples = size >> sw->info.shift; 932 if (!live) { 947 samples = size >> sw->Props.cShift; 948 if (!live) 949 { 950 LogFlow(("DrvAudio: Error: No Live data \n")); 933 951 return 0; 934 952 } 935 953 936 swlim = (live * sw->ratio) >> 32; 954 swlim = (live * sw->State.ratio) >> 32; 955 csLimit = swlim; 937 956 swlim = audio_MIN (swlim, samples); 938 939 while (swlim){940 src = hw-> conv_buf + rpos;941 isamp = hw-> wpos- rpos;957 while (swlim) 958 { 959 src = hw->pConversionBuf + rpos; 960 isamp = hw->offWrite - rpos; 942 961 /* XXX: <= ? */ 943 if (isamp <= 0) { 944 isamp = hw->samples - rpos; 945 } 946 947 if (!isamp) { 962 if (isamp <= 0) 963 isamp = hw->cSamples - rpos; 964 965 if (!isamp) 948 966 break; 949 } 967 950 968 osamp = swlim; 951 952 if (audio_bug (AUDIO_FUNC, osamp < 0)){953 dolog ("osamp=%d\n", osamp);969 if (osamp < 0) 970 { 971 LogFlow(("Error: osamp=%d\n", osamp)); 954 972 return 0; 955 973 } … … 958 976 Log(("audio_pcm_sw_read: buffer overflow!! ret = %d, osamp = %d, buf_samples = %d\n", 959 977 ret, osamp, sw->buf_samples)); 960 st_rate_flow (sw-> rate, src, dst, &isamp, &osamp);978 st_rate_flow (sw->State.rate, src, dst, &isamp, &osamp); 961 979 swlim -= osamp; 962 rpos = (rpos + isamp) % hw-> samples;980 rpos = (rpos + isamp) % hw->cSamples; 963 981 dst += osamp; 964 982 ret += osamp; 965 983 total += isamp; 966 984 } 967 968 if (ret > sw->buf_samples) 969 Log(("audio_pcm_sw_read: buffer overflow!! ret = %d, buf_samples = %d\n", ret, sw->buf_samples)); 970 sw->clip (buf, sw->buf, ret); 971 sw->total_hw_samples_acquired += total; 972 return ret << sw->info.shift; 985 sw->cHostSamplesAcquired = sw->cHostSamplesAcquired + total; 986 if (csLimit >= samples) 987 { 988 /* read audio that is there in the ring buffer */ 989 cSamplesInRingBuffer = IORingBufferUsed(pThis->pAudioReadBuf) / sizeof(PDMHOSTSTEREOSAMPLE); 990 if (cSamplesInRingBuffer >= 45000) /* 750 K Buffer / sizeof(PDMHOSTSTEREOSAMPLE)*/ 991 { 992 IORingBufferReset(pThis->pAudioReadBuf); 993 cSamplesInRingBuffer = 0; 994 } 995 if (cSamplesInRingBuffer > samples) 996 cSamplesInRingBuffer = samples; 997 cSamplesRead = 0, cbToRead = 0; 998 while (cSamplesRead < cSamplesInRingBuffer) 999 { 1000 cbToRead = cSamplesInRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE); 1001 IORingBufferAquireReadBlock(pThis->pAudioReadBuf, cbToRead, 1002 &pcSrc, &cbToRead); 1003 if (!cbToRead) 1004 LogFlow(("DrvAudio: There are no audio in queue to be written. \n")); 1005 memcpy((uint8_t *)pSampleBuf, pcSrc, cbToRead); 1006 cSamplesRead = cSamplesRead + (cbToRead / sizeof(PDMHOSTSTEREOSAMPLE)); 1007 /* Release the read buffer, so it could be used for new data. */ 1008 IORingBufferReleaseReadBlock(pThis->pAudioReadBuf, cbToRead); 1009 } 1010 memcpy((uint8_t *)pSampleBuf + cbToRead, (uint8_t *)sw->buf, 1011 (samples - cSamplesRead) * sizeof(PDMHOSTSTEREOSAMPLE)); 1012 1013 memcpy((uint8_t *)buf, (uint8_t *)pSampleBuf, samples * sizeof(PDMHOSTSTEREOSAMPLE)); 1014 1015 csToWrite = ret - (samples - cSamplesRead); 1016 csAvail = IORingBufferFree(pThis->pAudioReadBuf) / sizeof(PDMHOSTSTEREOSAMPLE); 1017 csWritten = 0; 1018 while (csWritten < csToWrite) 1019 { 1020 cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE); 1021 IORingBufferAquireWriteBlock(pThis->pAudioReadBuf, cbToWrite, &pcDst, &cbToWrite); 1022 1023 csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE); 1024 if (RT_UNLIKELY(csToWrite == 0)) 1025 { 1026 IORingBufferReleaseWriteBlock(pThis->pAudioReadBuf, cbToWrite); 1027 IORingBufferReset(pThis->pAudioReadBuf); 1028 LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n")); 1029 } 1030 1031 /* copy the audio data not accepted by the backend to the ring buffer */ 1032 memcpy(pcDst, (uint8_t*)sw->buf + ((samples - cSamplesRead) * sizeof(PDMHOSTSTEREOSAMPLE)) + 1033 (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite); 1034 IORingBufferReleaseWriteBlock(pThis->pAudioReadBuf, cbToWrite); 1035 csWritten += csToWrite; 1036 } 1037 return samples << sw->Props.cShift; 1038 } 1039 else if (csLimit < samples && csLimit != 0) 1040 { 1041 csAvail = IORingBufferFree(pThis->pAudioReadBuf) / sizeof(PDMHOSTSTEREOSAMPLE); 1042 csWritten = 0; 1043 while (csWritten < ret) 1044 { 1045 csToWrite = ret - csWritten; 1046 cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE); 1047 IORingBufferAquireWriteBlock(pThis->pAudioReadBuf, cbToWrite, &pcDst, &cbToWrite); 1048 1049 csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE); 1050 if (RT_UNLIKELY(csToWrite == 0)) 1051 LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n")); 1052 1053 /* copy the audio data not accepted by the backend to the ring buffer */ 1054 memcpy(pcDst, (uint8_t*)sw->buf + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite); 1055 IORingBufferReleaseWriteBlock(pThis->pAudioReadBuf, cbToWrite); 1056 csWritten += csToWrite; 1057 } 1058 memcpy(buf, pSampleBuf, 0); 1059 return 0; 1060 } 1061 return 0; 973 1062 } 974 1063 … … 976 1065 * Hard voice (playback) 977 1066 */ 978 static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep) 979 { 980 SWVoiceOut *sw; 1067 static int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep) 1068 { 1069 PPDMGSTVOICEOUT sw; 1070 PPDMGSTVOICEOUT pIter; 981 1071 int m = INT_MAX; 982 1072 int nb_live = 0; 983 984 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 985 if (sw->active || !sw->empty) { 986 m = audio_MIN (m, sw->total_hw_samples_mixed); 1073 LogFlow(("Hard Voice Playback \n")); 1074 1075 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 1076 { 1077 sw = pIter; 1078 if (sw->State.fActive || !sw->State.fEmpty) 1079 { 1080 m = audio_MIN (m, sw->cSamplesMixed); 987 1081 nb_live += 1; 988 1082 } … … 993 1087 } 994 1088 995 int audio_pcm_hw_get_live_out2 ( HWVoiceOut *hw, int *nb_live)1089 int audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live) 996 1090 { 997 1091 int smin; … … 1002 1096 return 0; 1003 1097 } 1004 else { 1098 else 1099 { 1005 1100 int live = smin; 1006 1101 1007 if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) { 1008 dolog ("live=%d hw->samples=%d\n", live, hw->samples); 1102 if (live < 0 || live > hw->cSamples) 1103 { 1104 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 1009 1105 return 0; 1010 1106 } … … 1013 1109 } 1014 1110 1015 int audio_pcm_hw_get_live_out ( HWVoiceOut *hw)1111 int audio_pcm_hw_get_live_out (PPDMHOSTVOICEOUT hw) 1016 1112 { 1017 1113 int nb_live; … … 1019 1115 1020 1116 live = audio_pcm_hw_get_live_out2 (hw, &nb_live); 1021 if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) { 1022 dolog ("live=%d hw->samples=%d\n", live, hw->samples); 1117 if (live < 0 || live > hw->cSamples) 1118 { 1119 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 1023 1120 return 0; 1024 1121 } … … 1026 1123 } 1027 1124 1125 #if 0 1028 1126 /* 1029 1127 * Soft voice (playback) 1030 1128 */ 1031 int audio_pcm_sw_write ( SWVoiceOut *sw, void *buf, int size)1129 int audio_pcm_sw_write (PDRVAUDIO pThis,PPDMGSTVOICEOUT pGstVoiceOut, void *buf, int size) 1032 1130 { 1033 1131 int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; 1034 1132 int ret = 0, pos = 0, total = 0; 1035 1133 1036 if (! sw) {1134 if (!pGstVoiceOut) { 1037 1135 return size; 1038 1136 } 1039 1137 1040 hwsamples = sw->hw->samples; 1041 1042 live = sw->total_hw_samples_mixed; 1043 if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){ 1044 dolog ("live=%d hw->samples=%d\n", live, hwsamples); 1045 return 0; 1138 hwsamples = pGstVoiceOut->pHostVoiceOut->cSamples; 1139 LogFlow(("DrvAudio: hwSamples = %d\n", hwsamples)); 1140 1141 live = pGstVoiceOut->cSamplesMixed; 1142 if (live < 0 || live > hwsamples) 1143 { 1144 LogFlow(("Error: live=%d hw->samples=%d\n", live, hwsamples)); 1145 return size; 1046 1146 } 1047 1147 1048 1148 if (live == hwsamples) { 1049 #ifdef DEBUG_OUT 1050 dolog ("%s is full %d\n", sw->name, live); 1051 #endif 1052 return 0; 1053 } 1054 1055 wpos = (sw->hw->rpos + live) % hwsamples; 1056 samples = size >> sw->info.shift; 1149 LogFlow(("DrvAudio: full %d\n", live)); 1150 return size; 1151 } 1152 1153 wpos = (pGstVoiceOut->pHostVoiceOut->offRead + live) % hwsamples; 1154 samples = size >> pGstVoiceOut->Props.cShift; 1057 1155 1058 1156 dead = hwsamples - live; 1059 swlim = ((int64_t) dead << 32) / sw->ratio;1157 swlim = ((int64_t) dead << 32) / pGstVoiceOut->State.ratio; 1060 1158 swlim = audio_MIN (swlim, samples); 1061 if (swlim > sw->buf_samples)1159 if (swlim > pGstVoiceOut->cSamples) 1062 1160 Log(("audio_pcm_sw_write: buffer overflow!! swlim = %d, buf_samples = %d\n", 1063 swlim, pos, sw->buf_samples)); 1161 swlim, pos, pGstVoiceOut->cSamples)); 1162 //swlim = samples; 1064 1163 if (swlim) { 1065 #ifndef VBOX 1066 sw->conv (sw->buf, buf, swlim, &sw->vol); 1067 #else 1068 sw->conv (sw->buf, buf, swlim, &sum_out_volume); 1069 #endif 1070 } 1071 1072 while (swlim) { 1164 convAudio (pGstVoiceOut->buf, buf, swlim, &sum_out_volume); 1165 } 1166 1167 while (swlim) 1168 { 1073 1169 dead = hwsamples - live; 1074 1170 left = hwsamples - wpos; … … 1079 1175 isamp = swlim; 1080 1176 osamp = blck; 1081 if (pos + isamp > sw->buf_samples) 1177 //osamp = left; 1178 if (pos + isamp > pGstVoiceOut->cSamples) 1082 1179 Log(("audio_pcm_sw_write: buffer overflow!! isamp = %d, pos = %d, buf_samples = %d\n", 1083 isamp, pos, sw->buf_samples));1180 isamp, pos, pGstVoiceOut->cSamples)); 1084 1181 st_rate_flow_mix ( 1085 sw->rate,1086 sw->buf + pos,1087 sw->hw->mix_buf + wpos,1182 pGstVoiceOut->State.rate, 1183 pGstVoiceOut->buf + pos, 1184 pGstVoiceOut->pHostVoiceOut->pHostSterioSampleBuf + wpos, 1088 1185 &isamp, 1089 1186 &osamp … … 1097 1194 } 1098 1195 1099 sw->total_hw_samples_mixed += total; 1100 sw->empty = sw->total_hw_samples_mixed == 0; 1101 1102 #ifdef DEBUG_OUT 1103 dolog ( 1104 "%s: write size %d ret %d total sw %d\n", 1105 SW_NAME (sw), 1106 size >> sw->info.shift, 1196 pGstVoiceOut->cSamplesMixed += total; 1197 pGstVoiceOut->State.fEmpty = pGstVoiceOut->cSamplesMixed == 0; 1198 1199 LogFlow(( 1200 "write size %d ret %d total sw %d\n", 1201 size >> pGstVoiceOut->Props.cShift, 1107 1202 ret, 1108 sw->total_hw_samples_mixed 1109 ); 1203 pGstVoiceOut->cSamplesMixed 1204 )); 1205 1206 //return ret << pGstVoiceOut->Props.cShift; 1207 return size; 1208 } 1110 1209 #endif 1111 1210 1112 return ret << sw->info.shift; 1211 /* 1212 * Soft voice (playback) 1213 */ 1214 int audio_pcm_sw_write(PDRVAUDIO pThis, PPDMGSTVOICEOUT pGstVoiceOut, void *buf, int size) 1215 { 1216 int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck; 1217 int ret = 0, pos = 0, total = 0; 1218 uint8_t *pcDst = NULL; 1219 uint8_t *pcSrc = NULL; 1220 uint32_t cbToWrite; 1221 uint32_t cSamplesInQueue = 0; 1222 uint32_t cbSamplesInQueue = 0; 1223 uint32_t cbTotalSamples = 0; 1224 uint32_t cTotalSamples = 0; 1225 uint32_t cSamplesAccepted = 0; 1226 /* sample buf to hold the samples that have been passed from Device and to hold samples from the queue 1227 * 500 KB. 1228 */ 1229 uint8_t SampleBuf[512000]; 1230 PDMHOSTSTEREOSAMPLE pdmSampleBuf[5120]; 1231 uint32_t cSamplesLeft; 1232 1233 if (!pGstVoiceOut) 1234 { 1235 LogFlow(("DrvAudio: GstVoiceOut NULL \n")); 1236 return size; 1237 } 1238 LogFlow(("DrvAudio: size to write = %d\n", size)); 1239 1240 hwsamples = pGstVoiceOut->pHostVoiceOut->cSamples; 1241 1242 live = pGstVoiceOut->cSamplesMixed; 1243 if (live < 0 || live > hwsamples) 1244 { 1245 /* save all the samples in the ring buffer, and return as if all the samples have been accepted. 1246 * Saving in ring buffer as host buffer is full and can't take any more samples. 1247 */ 1248 cbToWrite = size; 1249 LogFlow(("DrvAudio: Error: live=%d hw->samples=%d\n", live, hwsamples)); 1250 //return 0 1251 IORingBufferAquireWriteBlock(pThis->pAudioWriteBuf, cbToWrite, &pcDst, &cbToWrite); 1252 if (RT_UNLIKELY(cbToWrite == 0)) 1253 LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n")); 1254 1255 /* copy the audio data not accepted by the backend to the ring buffer */ 1256 memcpy(pcDst, (uint8_t*)buf , cbToWrite); 1257 1258 /* Rlease the ring buffer */ 1259 IORingBufferReleaseWriteBlock(pThis->pAudioWriteBuf, cbToWrite); 1260 return size; 1261 } 1262 1263 if (live == hwsamples) 1264 { 1265 /* save all the samples in the ring buffer, and return as if all the samples have been accepted. 1266 * Saving in ring buffer as host buffer is full and can't take any more samples. 1267 */ 1268 LogFlow(("DrvAudio: full %d\n", live)); 1269 //return 0; 1270 cbToWrite = size; 1271 IORingBufferAquireWriteBlock(pThis->pAudioWriteBuf, cbToWrite, &pcDst, &cbToWrite); 1272 if (RT_UNLIKELY(cbToWrite == 0)) 1273 LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n")); 1274 1275 /* copy the audio data not accepted by the backend to the ring buffer */ 1276 memcpy(pcDst, (uint8_t*)buf, cbToWrite); 1277 1278 /* Rlease the ring buffer */ 1279 IORingBufferReleaseWriteBlock(pThis->pAudioWriteBuf, cbToWrite); 1280 return size; 1281 } 1282 1283 wpos = (pGstVoiceOut->pHostVoiceOut->offRead + live) % hwsamples; 1284 /* @todo check it. to convert size to num of samples */ 1285 //samples = cbTotalSamples >> pGstVoiceOut->Props.cShift; 1286 samples = size >> pGstVoiceOut->Props.cShift; 1287 1288 dead = hwsamples - live; 1289 /* swlim is upper limit of max no. of samples that can be transferred in this cycle to backend */ 1290 swlim = ((int64_t) dead << 32) / pGstVoiceOut->State.ratio; 1291 swlim = audio_MIN (swlim, samples); 1292 1293 LogFlow(("DrvAudio: swlim = %d\n", swlim)); 1294 1295 if (swlim > pGstVoiceOut->cSamples) 1296 Log(("audio_pcm_sw_write: buffer overflow!! swlim = %d, buf_samples = %d\n", 1297 swlim, pos, pGstVoiceOut->cSamples)); 1298 cSamplesAccepted = swlim; 1299 /* find out how much of the queue is full. */ 1300 cbSamplesInQueue = IORingBufferUsed(pThis->pAudioWriteBuf); 1301 /* if ring buffer hold samples > 100 KB, discard samples */ 1302 if (cbSamplesInQueue > 102400) 1303 { 1304 LogFlow(("DrvAudio: Samples in ring buffer > 300 KB. Discarding \n")); 1305 cbSamplesInQueue = 0; 1306 IORingBufferReset(pThis->pAudioWriteBuf); 1307 } 1308 /* read only that much samples as requried to be processed */ 1309 if (cbSamplesInQueue > (cSamplesAccepted << pGstVoiceOut->Props.cShift)) 1310 cbSamplesInQueue = (cSamplesAccepted << pGstVoiceOut->Props.cShift); 1311 1312 LogFlow(("DrvAudio: Samples in queue =%d and its size=%d\n", 1313 cbSamplesInQueue >> pGstVoiceOut->Props.cShift, cbSamplesInQueue)); 1314 1315 /* read all the samples that are there in the queue and copy them to SampleBuf . 1316 * Reading all samples from the ring buffer as we need to send these samples first 1317 * and then add the samples received in this iteration to the ring buffer. 1318 */ 1319 IORingBufferAquireReadBlock(pThis->pAudioWriteBuf, cbSamplesInQueue, &pcSrc, &cbSamplesInQueue); 1320 if (!cbSamplesInQueue) 1321 LogFlow(("DrvAudio: There are no audio in queue to be written. \n")); 1322 1323 1324 memcpy(SampleBuf, pcSrc, cbSamplesInQueue); 1325 /* Append the buf to samples that were there in the queue. SampBuf holds all the data to transfer */ 1326 memcpy(SampleBuf + cbSamplesInQueue, buf, size); 1327 /* Release the read buffer, so it could be used for new data. */ 1328 IORingBufferReleaseReadBlock(pThis->pAudioWriteBuf, cbSamplesInQueue); 1329 1330 /* reset the ring buffer to accept new data. */ 1331 1332 /* cbTotalSamples = size of samples passed from the device + size of samples in the queue */ 1333 cbTotalSamples = size + cbSamplesInQueue; 1334 LogFlow(("DrvAudio: size of samples read = %d and sz of samples recd = %d\n", 1335 cbSamplesInQueue, size)); 1336 LogFlow(("DrvAudio: TotalSamples = %d\n", cbTotalSamples >> pGstVoiceOut->Props.cShift)); 1337 if (swlim) { 1338 /* conversion engine: dest, source, num of samples, volume */ 1339 convAudio (pGstVoiceOut->buf, SampleBuf, swlim, &sum_out_volume); 1340 } 1341 1342 while (swlim) 1343 { 1344 dead = hwsamples - live; 1345 left = hwsamples - wpos; 1346 blck = audio_MIN (dead, left); 1347 if (!blck) { 1348 break; 1349 } 1350 isamp = swlim; 1351 osamp = blck; 1352 if (pos + isamp > pGstVoiceOut->cSamples) 1353 Log(("audio_pcm_sw_write: buffer overflow!! isamp = %d, pos = %d, buf_samples = %d\n", 1354 isamp, pos, pGstVoiceOut->cSamples)); 1355 /* mix and write to the host buffer to be read by the host during playout */ 1356 st_rate_flow_mix ( 1357 pGstVoiceOut->State.rate, 1358 pGstVoiceOut->buf + pos, 1359 pGstVoiceOut->pHostVoiceOut->pHostSterioSampleBuf + wpos, 1360 &isamp, 1361 &osamp 1362 ); 1363 ret += isamp; 1364 swlim -= isamp; 1365 pos += isamp; 1366 live += osamp; 1367 wpos = (wpos + osamp) % hwsamples; 1368 total += osamp; 1369 } 1370 1371 pGstVoiceOut->cSamplesMixed += total; 1372 pGstVoiceOut->State.fEmpty = pGstVoiceOut->cSamplesMixed == 0; 1373 1374 cSamplesLeft = (cbTotalSamples >> pGstVoiceOut->Props.cShift) - cSamplesAccepted ; 1375 LogFlow(("DrvAudio: cSamplesLeft = %d\n", cSamplesLeft)); 1376 if (cSamplesLeft > 0) 1377 { 1378 cbToWrite = cSamplesLeft << pGstVoiceOut->Props.cShift; 1379 /* max capacity of ring buffer is 516196 */ 1380 //cbToWrite = audio_MIN(cbToWrite, 516196); 1381 IORingBufferAquireWriteBlock(pThis->pAudioWriteBuf, cbToWrite, &pcDst, &cbToWrite); 1382 if (RT_UNLIKELY(cbToWrite == 0)) 1383 LogFlow(("DrvAudio: NO space in Ring buffer. Not doing anything, just discarding samples.\n")); 1384 1385 /* copy the audio data not accepted by the backend to the ring buffer */ 1386 memcpy(pcDst, (uint8_t*)SampleBuf + (cSamplesAccepted << pGstVoiceOut->Props.cShift), cbToWrite); 1387 1388 /* Rlease the ring buffer */ 1389 IORingBufferReleaseWriteBlock(pThis->pAudioWriteBuf, cbToWrite); 1390 } 1391 /* convert no of samples to bytes */ 1392 return size; 1113 1393 } 1114 1394 … … 1116 1396 static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info) 1117 1397 { 1118 dolog("%s: bits %d, sign %d, freq %d, nchan %d\n",1119 cap, info->bits, info->sign, info->freq, info->nchannels) ;1398 LogFlow(("%s: bits %d, sign %d, freq %d, nchan %d\n", 1399 cap, info->bits, info->sign, info->freq, info->nchannels)); 1120 1400 } 1121 1401 #endif 1122 1402 1123 #define DAC 1124 #include "audio_template.h" 1125 #undef DAC 1126 #include "audio_template.h" 1127 1128 int AUD_write (SWVoiceOut *sw, void *buf, int size) 1403 int AUD_get_buffer_size_out (PPDMGSTVOICEOUT sw) 1404 { 1405 return sw->pHostVoiceOut->cSamples << sw->pHostVoiceOut->Props.cShift; 1406 } 1407 1408 static int audio_get_avail (PPDMGSTVOICEIN sw) 1409 { 1410 int live; 1411 1412 if (!sw) 1413 { 1414 LogFlow(("Error Voice Input Stream NUL \n")); 1415 return 0; 1416 } 1417 1418 live = sw->hw->cSamplesCaptured - sw->cHostSamplesAcquired; 1419 if (live < 0 || live > sw->hw->cSamples) 1420 { 1421 LogFlow(("DrvAudio: Error, live=%d sw->hw->samples=%d\n", live, sw->hw->cSamples)); 1422 return 0; 1423 } 1424 return (((int64_t) live << 32) / sw->State.ratio) << sw->Props.cShift; 1425 } 1426 1427 static int audio_get_free(PPDMGSTVOICEOUT sw) 1428 { 1429 int live, dead; 1430 1431 if (!sw) 1432 { 1433 LogFlow(("DrvAudio: Error, guest voice output stream null \n")); 1434 return 0; 1435 } 1436 1437 live = sw->cSamplesMixed; 1438 1439 if (live < 0 || live > sw->pHostVoiceOut->cSamples) 1440 { 1441 LogFlow(("DrvAudio: Error, live=%d sw->hw->samples=%d\n", live, sw->pHostVoiceOut->cSamples)); 1442 return 0; 1443 } 1444 dead = sw->pHostVoiceOut->cSamples - live; 1445 return (((int64_t) dead << 32) / sw->State.ratio) << sw->Props.cShift; 1446 } 1447 1448 static void audio_capture_mix_and_clear (PDRVAUDIO pThis, PPDMHOSTVOICEOUT hw, int rpos, int samples) 1449 { 1450 int n; 1451 LogFlow(("audio_capture_mix_and_clear \n")); 1452 if (hw->fEnabled) 1453 { 1454 SWVoiceCap *sc; 1455 SWVoiceCap *pIter; 1456 1457 RTListForEach(&hw->HeadCapturedVoice, pIter, SWVoiceCap, ListCapturedVoice) 1458 { 1459 sc = pIter; 1460 PPDMGSTVOICEOUT sw = &sc->sw; 1461 int rpos2 = rpos; 1462 1463 n = samples; 1464 while (n) 1465 { 1466 int till_end_of_hw = hw->cSamples - rpos2; 1467 int to_write = audio_MIN (till_end_of_hw, n); 1468 int bytes = to_write << hw->Props.cShift; 1469 int written; 1470 1471 sw->buf = hw->pHostSterioSampleBuf + rpos2; 1472 written = audio_pcm_sw_write (pThis, sw, NULL, bytes); 1473 if (written - bytes) { 1474 LogFlow(("Could not mix %d bytes into a capture " 1475 "buffer, mixed %d\n", 1476 bytes, written)); 1477 break; 1478 } 1479 n -= to_write; 1480 rpos2 = (rpos2 + to_write) % hw->cSamples; 1481 } 1482 } 1483 } 1484 1485 n = audio_MIN (samples, hw->cSamples - rpos); 1486 mixeng_sniff_and_clear (hw, hw->pHostSterioSampleBuf + rpos, n); 1487 mixeng_sniff_and_clear (hw, hw->pHostSterioSampleBuf, samples - n); 1488 } 1489 1490 static void drvAudioPlayOut(PDRVAUDIO pThis) 1491 { 1492 PPDMHOSTVOICEOUT hw = NULL; 1493 PPDMGSTVOICEOUT sw; 1494 PPDMGSTVOICEOUT pIter; 1495 PPDMGSTVOICEOUT pIter1; 1496 1497 while ((hw = drvAudioHlpPcmHwFindAnyEnabledOut(pThis, hw))) 1498 { 1499 int played; 1500 int live, myfree, nb_live, cleanup_required, prev_rpos; 1501 1502 live = audio_pcm_hw_get_live_out2 (hw, &nb_live); 1503 if (!nb_live) 1504 { 1505 LogFlow(("DrvAudio: Live samples 0\n")); 1506 live = 0; 1507 } 1508 1509 if (live < 0 || live > hw->cSamples) 1510 { 1511 LogFlow(("DrvAudio: live=%d hw->samples=%d\n", live, hw->cSamples)); 1512 continue; 1513 } 1514 1515 if (hw->pending_disable && !nb_live) 1516 { 1517 SWVoiceCap *sc; 1518 SWVoiceCap *pIter; 1519 hw->fEnabled = 0; 1520 hw->pending_disable = 0; 1521 pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hw, VOICE_DISABLE); 1522 RTListForEach(&hw->HeadCapturedVoice, pIter, SWVoiceCap , ListCapturedVoice) 1523 { 1524 sc = pIter; 1525 sc->sw.State.fActive = 0; 1526 drvAudioRecalcAndNotifyCapture(sc->cap); 1527 } 1528 continue; 1529 } 1530 1531 if (!live) 1532 { 1533 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 1534 { 1535 sw = pIter; 1536 if (sw->State.fActive) 1537 { 1538 myfree = audio_get_free (sw); 1539 if (myfree > 0) 1540 sw->callback.fn (sw->callback.opaque, myfree); 1541 } 1542 } 1543 continue; 1544 } 1545 1546 prev_rpos = hw->offRead; 1547 played = pThis->pHostDrvAudio->pfnPlayOut(pThis->pHostDrvAudio, hw); 1548 if (hw->offRead >= hw->cSamples) 1549 { 1550 LogFlow(("DrvAudio: hw->rpos=%d hw->samples=%d played=%d\n", 1551 hw->offRead, hw->cSamples, played)); 1552 hw->offRead = 0; 1553 } 1554 /* I think this code relates to the point to accomodate no of audio samples 1555 * that have got accumulated during the above call of pfnplayout. So , it basically 1556 * tries to mix the old samples that have already been played, new samples that have 1557 * been gathered in due time of playing. Mix them up and send it to audiosniffer for 1558 * to be sent to VRDP server to be played on the client. 1559 */ 1560 if (played) { 1561 audio_capture_mix_and_clear (pThis, hw, prev_rpos, played); 1562 } 1563 1564 cleanup_required = 0; 1565 RTListForEach(&hw->HeadGstVoiceOut, pIter1, PDMGSTVOICEOUT, ListGstVoiceOut) 1566 { 1567 sw = pIter1; 1568 if (!sw->State.fActive && sw->State.fEmpty) 1569 continue; 1570 1571 if (played > sw->cSamplesMixed) 1572 { 1573 LogFlow(("DrvAudio: played=%d sw->total_hw_samples_mixed=%d\n", 1574 played, sw->cSamplesMixed)); 1575 played = sw->cSamplesMixed; 1576 } 1577 1578 sw->cSamplesMixed -= played; 1579 1580 if (!sw->cSamplesMixed) 1581 { 1582 sw->State.fEmpty = 1; 1583 cleanup_required |= !sw->State.fActive && !sw->callback.fn; 1584 } 1585 1586 if (sw->State.fActive) 1587 { 1588 myfree = audio_get_free (sw); 1589 if (myfree > 0) 1590 sw->callback.fn (sw->callback.opaque, myfree); 1591 } 1592 } 1593 1594 if (cleanup_required) 1595 { 1596 PPDMGSTVOICEOUT sw1; 1597 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 1598 { 1599 sw = pIter; 1600 if (!sw->State.fActive && !sw->callback.fn) 1601 drvAudioHlpCloseOut(pThis, &pThis->qemuSoundCard, sw); 1602 } 1603 } 1604 } 1605 } 1606 1607 static void drvAudioPlayIn(PDRVAUDIO pThis) 1608 { 1609 PPDMHOSTVOICEIN hw = NULL; 1610 1611 while ((hw = drvAudioHlpPcmHwFindAnyEnabledIn(pThis, hw))) 1612 { 1613 PPDMGSTVOICEIN pIter; 1614 int captured, min; 1615 captured = pThis->pHostDrvAudio->pfnPlayIn(pThis->pHostDrvAudio, hw); 1616 1617 min = audio_pcm_hw_find_min_in (hw); 1618 hw->cSamplesCaptured += captured - min; 1619 hw->ts_helper += captured; 1620 1621 RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn) 1622 { 1623 pIter->cHostSamplesAcquired -= min; 1624 1625 if (pIter->State.fActive) 1626 { 1627 int avail; 1628 avail = audio_get_avail (pIter); 1629 if (avail > 0) 1630 { 1631 pIter->callback.fn(pIter->callback.opaque, avail); 1632 } 1633 } 1634 } 1635 } 1636 } 1637 1638 static void drvAudioCapture(PDRVAUDIO pThis) 1639 { 1640 CaptureVoiceOut *cap; 1641 CaptureVoiceOut *pIter; 1642 1643 RTListForEach(&pThis->HeadCapturedVoice, pIter, CaptureVoiceOut, ListCapturedVoice) 1644 { 1645 cap = pIter; 1646 int live, rpos, captured; 1647 PPDMHOSTVOICEOUT hw = &cap->hw; 1648 PPDMGSTVOICEOUT sw; 1649 PPDMGSTVOICEOUT pIter; 1650 1651 captured = live = audio_pcm_hw_get_live_out (hw); 1652 rpos = hw->offRead; 1653 while (live) 1654 { 1655 int left = hw->cSamples - rpos; 1656 int to_capture = audio_MIN (live, left); 1657 st_sample_t *src; 1658 struct capture_callback *cb; 1659 1660 src = hw->pHostSterioSampleBuf + rpos; 1661 clipAudio (cap->buf, src, to_capture); 1662 mixeng_sniff_and_clear (hw, src, to_capture); 1663 1664 rpos = (rpos + to_capture) % hw->cSamples; 1665 live -= to_capture; 1666 } 1667 hw->offRead = rpos; 1668 1669 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 1670 { 1671 sw = pIter; 1672 LogFlow(("6\n")); 1673 if (!sw->State.fActive && sw->State.fEmpty) { 1674 continue; 1675 } 1676 1677 if (captured > sw->cSamplesMixed) 1678 { 1679 LogFlow(("DrvAudio: captured=%d sw->total_hw_samples_mixed=%d\n", 1680 captured, sw->cSamplesMixed)); 1681 captured = sw->cSamplesMixed; 1682 } 1683 1684 sw->cSamplesMixed -= captured; 1685 sw->State.fEmpty = sw->cSamplesMixed == 0; 1686 } 1687 } 1688 } 1689 static void drvAudioTimer(PDRVAUDIO pThis) 1690 { 1691 drvAudioPlayOut(pThis); 1692 drvAudioPlayIn(pThis); 1693 drvAudioCapture(pThis); 1694 TMTimerSet (pThis->pTimer, TMTimerGet (pThis->pTimer) + pThis->ticks); 1695 } 1696 1697 static int audio_driver_init (PCFGMNODE pCfgHandle, PDRVAUDIO pThis, struct audio_driver *drv) 1698 { 1699 int max_voices; 1700 int voice_size; 1701 if (drv->options) 1702 { 1703 drvAudioProcessOptions(pCfgHandle, drv->name, drv->options); 1704 } 1705 if (!pThis->pHostDrvAudio->pfnInit(pThis->pHostDrvAudio)) 1706 { 1707 LogFlow(("DrvAudio: Could not init audio driver %p\n", pThis)); 1708 return VERR_GENERAL_FAILURE; 1709 } 1710 1711 max_voices = pThis->AudioConf.MaxHostVoicesOut; 1712 voice_size = pThis->AudioConf.szHostVoiceOut; 1713 pThis->cHostOutVoices = 1; 1714 if (pThis->cHostOutVoices > max_voices) 1715 { 1716 if (!max_voices) 1717 LogFlow(("Driver `%s' does not support \n", drv->name)); 1718 else 1719 LogFlow(("Driver `%s' does not support %d voices, max %d\n", 1720 drv->name, 1721 pThis->cHostOutVoices, 1722 max_voices)); 1723 pThis->cHostOutVoices = 1;//max_voices; 1724 } 1725 1726 if (!voice_size && max_voices) 1727 { 1728 LogFlow(("drv=`%s' voice_size=0 max_voices=%d\n", 1729 drv->name, max_voices)); 1730 pThis->cHostOutVoices = 0; 1731 } 1732 1733 if (voice_size && !max_voices) 1734 { 1735 LogFlow(("drv=`%s' voice_size=%d max_voices=0\n", 1736 drv->name, voice_size)); 1737 } 1738 1739 1740 max_voices = pThis->AudioConf.MaxHostVoicesIn; 1741 voice_size = pThis->AudioConf.szHostVoiceIn; 1742 1743 LogFlow(("DrvAudio: voice_size =%d max_voices=%d cHostInVoices=%d\n", voice_size, max_voices, pThis->cHostInVoices)); 1744 //pThis->cHostInVoices = 1; //@todo handle this 1745 if (pThis->cHostInVoices > max_voices) 1746 { 1747 if (!max_voices) 1748 LogFlow(("Driver `%s' does not support \n", drv->name)); 1749 else 1750 LogFlow(("Driver `%s' does not support %d voices, max %d\n", 1751 drv->name, 1752 pThis->cHostOutVoices, 1753 max_voices)); 1754 pThis->cHostInVoices = max_voices; 1755 } 1756 1757 if (!voice_size && max_voices) 1758 { 1759 LogFlow(("drv=`%s' voice_size=0 max_voices=%d\n", 1760 drv->name, max_voices)); 1761 //@todo in original code its 0, but I have made it 1 to avoid crash 1762 pThis->cHostInVoices = 0; 1763 } 1764 1765 if (voice_size && !max_voices) 1766 { 1767 LogFlow(("drv=`%s' voice_size=%d max_voices=0\n", 1768 drv->name, voice_size)); 1769 } 1770 return VINF_SUCCESS; 1771 } 1772 1773 static void audio_vm_change_state_handler (PPDMDRVINS pDrvIns,/* void *opaque,*/ int running) 1774 { 1775 PPDMHOSTVOICEOUT hwo = NULL; 1776 PPDMHOSTVOICEIN hwi = NULL; 1777 PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO); 1778 int op = running ? VOICE_ENABLE : VOICE_DISABLE; 1779 1780 while ((hwo = drvAudioHlpPcmHwFindAnyEnabledOut(pThis, hwo))) { 1781 pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hwo, op); 1782 } 1783 1784 while ((hwi = drvAudioHlpPcmHwFindAnyEnabledIn(pThis, hwi))) { 1785 pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hwi, op); 1786 } 1787 } 1788 1789 static void drvAudioExit(PPDMDRVINS pDrvIns) 1790 { 1791 PPDMHOSTVOICEOUT hwo = NULL; 1792 PPDMHOSTVOICEIN hwi = NULL; 1793 PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO); 1794 /* VBox change: audio_pcm_hw_find_any_enabled_out => audio_pcm_hw_find_any_out */ 1795 while ((hwo = drvAudioHlpPcmHwFindAnyOut(pThis, hwo))) 1796 { 1797 SWVoiceCap *sc; 1798 SWVoiceCap *pIter; 1799 1800 pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hwo, VOICE_DISABLE); 1801 pThis->pHostDrvAudio->pfnFiniOut(pThis->pHostDrvAudio, hwo); 1802 1803 RTListForEach(&hwo->HeadCapturedVoice, pIter, SWVoiceCap, ListCapturedVoice) 1804 { 1805 sc = pIter; 1806 CaptureVoiceOut *cap = sc->cap; 1807 struct capture_callback *cb; 1808 } 1809 } 1810 1811 /* VBox change: audio_pcm_hw_find_any_enabled_in => audio_pcm_hw_find_any_in */ 1812 while ((hwi = drvAudioHlpPcmHwFindAnyIn(pThis, hwi))) 1813 { 1814 pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hwi, VOICE_DISABLE); 1815 pThis->pHostDrvAudio->pfnFiniIn(pThis->pHostDrvAudio, hwi); 1816 } 1817 } 1818 1819 static DECLCALLBACK(void) audio_timer_helper (PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser) 1820 { 1821 PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO); 1822 drvAudioTimer(pThis); 1823 } 1824 1825 static struct audio_option audio_options[] = 1826 { 1827 /* DAC */ 1828 {"DACFixedSettings", AUD_OPT_BOOL, &conf.fixed_out.enabled, 1829 "Use fixed settings for host DAC", NULL, 0}, 1830 1831 {"DACFixedFreq", AUD_OPT_INT, &conf.fixed_out.settings.freq, 1832 "Frequency for fixed host DAC", NULL, 0}, 1833 1834 {"DACFixedFmt", AUD_OPT_FMT, &conf.fixed_out.settings.fmt, 1835 "Format for fixed host DAC", NULL, 0}, 1836 1837 {"DACFixedChannels", AUD_OPT_INT, &conf.fixed_out.settings.nchannels, 1838 "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0}, 1839 1840 {"DACVoices", AUD_OPT_INT, &conf.fixed_out.nb_voices, 1841 "Number of voices for DAC", NULL, 0}, 1842 1843 /* ADC */ 1844 {"ADCFixedSettings", AUD_OPT_BOOL, &conf.fixed_in.enabled, 1845 "Use fixed settings for host ADC", NULL, 0}, 1846 1847 {"ADCFixedFreq", AUD_OPT_INT, &conf.fixed_in.settings.freq, 1848 "Frequency for fixed host ADC", NULL, 0}, 1849 1850 {"ADCFixedFmt", AUD_OPT_FMT, &conf.fixed_in.settings.fmt, 1851 "Format for fixed host ADC", NULL, 0}, 1852 1853 {"ADCFixedChannels", AUD_OPT_INT, &conf.fixed_in.settings.nchannels, 1854 "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0}, 1855 1856 {"ADCVoices", AUD_OPT_INT, &conf.fixed_in.nb_voices, 1857 "Number of voices for ADC", NULL, 0}, 1858 1859 /* Misc */ 1860 {"TimerFreq", AUD_OPT_INT, &conf.period.hz, 1861 "Timer frequency in Hz (0 - use lowest possible)", NULL, 0}, 1862 1863 {"PLIVE", AUD_OPT_BOOL, &conf.plive, 1864 "(undocumented)", NULL, 0}, 1865 1866 {NULL, 0, NULL, NULL, NULL, 0} 1867 }; 1868 1869 static DECLCALLBACK (void) drvAudioRegisterCard(PPDMIAUDIOCONNECTOR pInterface, const char *name) 1870 { 1871 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1872 LogFlow(("DrvAudio: drvAudioRegisterCard \n")); 1873 pThis->qemuSoundCard.name = RTStrDup(name); 1874 } 1875 1876 static DECLCALLBACK(int) drvAudioInit(PCFGMNODE pCfgHandle, PPDMDRVINS pDrvIns, const char *drvname, PDRVAUDIO pDrvAudio) 1877 { 1878 size_t i; 1879 int done = 0; 1880 int rc; 1881 PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO); 1882 LogFlow(("DrvAudio: drvAudioInit pDrvAudio=%p and pDrvIns=%p\n", pDrvAudio, pDrvIns)); 1883 1884 RTListInit(&pDrvAudio->HeadHostVoiceOut); 1885 RTListInit(&pDrvAudio->HeadHostVoiceIn); 1886 RTListInit(&pDrvAudio->HeadHostVoiceIn); 1887 RTListInit(&pDrvAudio->HeadCapturedVoice); 1888 1889 /* get the configuration data from the backend */ 1890 pDrvAudio->pHostDrvAudio->pfnGetConf(pDrvAudio->pHostDrvAudio, &pDrvAudio->AudioConf); 1891 1892 rc = PDMDrvHlpTMTimerCreate (pDrvIns, TMCLOCK_VIRTUAL, audio_timer_helper, 1893 pThis, 0, "Audio timer", &pDrvAudio->pTimer); 1894 if (RT_FAILURE (rc)) 1895 { 1896 LogRel(("DrvAudio: Failed to create timer \n")); 1897 return rc; 1898 } 1899 1900 drvAudioProcessOptions(pCfgHandle, "AUDIO", audio_options); 1901 1902 pDrvAudio->cHostOutVoices = conf.fixed_out.nb_voices; 1903 pDrvAudio->cHostInVoices = conf.fixed_in.nb_voices; 1904 1905 pDrvAudio->ticks = 200; /* initialization of ticks */ 1906 1907 /* initialization of audio buffer. Create ring buffer of around 200 KB each . */ 1908 IORingBufferCreate(&pDrvAudio->pAudioWriteBuf, 512000); /* 500 KB */ 1909 1910 /* allocating space for about 500 msec of audio data 48KHz, 128 bit sample 1911 * (guest format - PDMHOSTSTEREOSAMPLE) and dual channel 1912 */ 1913 IORingBufferCreate(&pDrvAudio->pAudioReadBuf, 768000); /* 750 KB */ 1914 1915 1916 if (pDrvAudio->cHostOutVoices <= 0) 1917 { 1918 LogFlow(("Bogus number of playback voices %d, setting to 1\n", pDrvAudio->cHostOutVoices)); 1919 pDrvAudio->cHostOutVoices = 1; 1920 } 1921 1922 if (pDrvAudio->cHostInVoices <= 0) 1923 { 1924 LogFlow(("Bogus number of capture voices %d, setting to 0\n", pDrvAudio->cHostInVoices)); 1925 //@todo in original code its set to 0 currently being set to 1 to ensure atleas 1 voice IN 1926 pDrvAudio->cHostInVoices = 1; 1927 } 1928 LogFlow(("Audio: Trying driver '%s'.\n", drvname)); 1929 1930 if (drvname) 1931 { 1932 int found = 0; 1933 for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) 1934 { 1935 /* @todo: audioVRDE name wont be visible here. So hardcoding */ 1936 if (!strcmp (drvname, drvtab[i]->name) || !strcmp(drvname, "AudioVRDE")) 1937 { 1938 if (!strcmp(drvname, "AudioVRDE")) 1939 { 1940 struct audio_driver vrde_audio_driver = 1941 { 1942 INIT_FIELD (name = ) "AudioVRDE", 1943 INIT_FIELD (descr = ) "AudioVRDE http://www.pulseaudio.org", 1944 INIT_FIELD (options = ) NULL, 1945 }; 1946 struct audio_driver *drvtabAudioVRDE = &vrde_audio_driver; 1947 done = !audio_driver_init (pCfgHandle, pDrvAudio, drvtabAudioVRDE); 1948 } 1949 else 1950 { 1951 done = !audio_driver_init (pCfgHandle, pDrvAudio, drvtab[i]); 1952 } 1953 found = 1; 1954 break; 1955 } 1956 } 1957 1958 if (!found) 1959 { 1960 LogFlow(("Audio: Unknown audio driver `%s'\n", drvname)); 1961 } 1962 } 1963 1964 if (!done) 1965 { 1966 for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) { 1967 if (drvtab[i]->can_be_default) { 1968 LogRel(("Audio: Initialization of driver '%s' failed, trying '%s'.\n",drvname, drvtab[i]->name)); 1969 drvname = drvtab[i]->name; 1970 done = !audio_driver_init (pCfgHandle, pDrvAudio, drvtab[i]); 1971 } 1972 } 1973 } 1974 1975 if (!done) { 1976 done = !audio_driver_init (pCfgHandle, pThis, &no_audio_driver); 1977 if (!done) { 1978 LogFlow(("Could not initialize audio subsystem\n")); 1979 } 1980 else { 1981 LogRel(("Audio: Initialization of driver '%s' failed, using NULL driver.\n", drvname)); 1982 LogFlow(("warning: Using timer based audio emulation\n")); 1983 } 1984 } 1985 if (done) 1986 { 1987 if (conf.period.hz <= 0) 1988 { 1989 if (conf.period.hz < 0) 1990 { 1991 LogFlow(("warning: Timer period is negative - %d " 1992 "treating as zero\n", 1993 conf.period.hz)); 1994 } 1995 pDrvAudio->ticks = 1; 1996 } 1997 else 1998 { 1999 pDrvAudio->ticks = PDMDrvHlpTMGetVirtualFreq(pDrvIns) / conf.period.hz; 2000 } 2001 } 2002 else { 2003 /* XXX */ 2004 rc = TMR3TimerDestroy (pDrvAudio->pTimer); 2005 return rc; 2006 } 2007 TMTimerSet (pDrvAudio->pTimer, TMTimerGet (pDrvAudio->pTimer) + pDrvAudio->ticks); 2008 return VINF_SUCCESS; 2009 } 2010 static DECLCALLBACK(int) drvAudioInitNull(PPDMIAUDIOCONNECTOR pInterface) 2011 { 2012 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2013 return audio_driver_init(NULL, pThis, &no_audio_driver); 2014 } 2015 2016 static DECLCALLBACK(int) drvAudioWrite(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw, void *buf, int size) 1129 2017 { 1130 2018 int bytes; 1131 2019 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2020 if (!sw || size < 0) 2021 { 2022 LogFlow(("DrvAudio: GstVoiceOut is NULL \n")); 2023 /* XXX: Consider options */ 2024 return size; 2025 } 2026 2027 if (!sw->pHostVoiceOut->fEnabled) { 2028 return 0; 2029 } 2030 bytes = audio_pcm_sw_write(pThis, sw, buf, size); 2031 return bytes; 2032 } 2033 2034 static DECLCALLBACK(int) drvAudioRead(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN sw, void *buf, int size) 2035 { 2036 int bytes; 2037 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1132 2038 if (!sw) { 1133 2039 /* XXX: Consider options */ … … 1136 2042 1137 2043 if (!sw->hw->enabled) { 1138 dolog ("Writing to disabled voice %s\n", SW_NAME (sw));2044 LogFlow(("DrvAudio: Reading from disabled voice \n")); 1139 2045 return 0; 1140 2046 } 1141 1142 bytes = sw->hw->pcm_ops->write (sw, buf, size); 2047 bytes = audio_pcm_sw_read(pThis, sw, (PPDMHOSTSTEREOSAMPLE)buf, size); 1143 2048 return bytes; 1144 2049 } 1145 2050 1146 int AUD_read (SWVoiceIn *sw, void *buf, int size) 1147 { 1148 int bytes; 1149 1150 if (!sw) { 1151 /* XXX: Consider options */ 1152 return size; 1153 } 1154 1155 if (!sw->hw->enabled) { 1156 dolog ("Reading from disabled voice %s\n", SW_NAME (sw)); 1157 return 0; 1158 } 1159 1160 bytes = sw->hw->pcm_ops->read (sw, buf, size); 1161 return bytes; 1162 } 1163 1164 int AUD_get_buffer_size_out (SWVoiceOut *sw) 1165 { 1166 return sw->hw->samples << sw->hw->info.shift; 1167 } 1168 1169 void AUD_set_active_out (SWVoiceOut *sw, int on) 1170 { 1171 HWVoiceOut *hw; 1172 1173 if (!sw) { 2051 static DECLCALLBACK(void) drvAudioIsSetOutVolume (PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw, int mute, uint8_t lvol, uint8_t rvol) 2052 { 2053 if (sw) 2054 { 2055 sw->State.uVolumeMute = mute; 2056 sw->State.uVolumeLeft = (uint32_t)lvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */ 2057 sw->State.uVolumeRight = (uint32_t)rvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */ 2058 } 2059 } 2060 2061 2062 static DECLCALLBACK(void) drvAudioSetVolume (PPDMIAUDIOCONNECTOR pInterface, int *mute, uint8_t *lvol, uint8_t *rvol) 2063 { 2064 volume_t vol; 2065 const char *name; 2066 2067 uint32_t u32VolumeLeft = (uint32_t)*lvol; 2068 uint32_t u32VolumeRight = (uint32_t)*rvol; 2069 /* 0x00..0xff => 0x01..0x100 */ 2070 if (u32VolumeLeft) 2071 u32VolumeLeft++; 2072 if (u32VolumeRight) 2073 u32VolumeRight++; 2074 vol.mute = *mute; 2075 vol.l = u32VolumeLeft * 0x800000; /* maximum is 0x80000000 */ 2076 vol.r = u32VolumeRight * 0x800000; /* maximum is 0x80000000 */ 2077 sum_out_volume.mute = 0; 2078 sum_out_volume.l = ASMMultU64ByU32DivByU32(INT_MAX, INT_MAX, 0x80000000U); 2079 sum_out_volume.r = ASMMultU64ByU32DivByU32(INT_MAX, INT_MAX, 0x80000000U); 2080 } 2081 2082 static DECLCALLBACK(void) drvAudioEnableOut (PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw, int on) 2083 { 2084 PPDMHOSTVOICEOUT hw; 2085 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2086 2087 if (!sw) 1174 2088 return; 1175 } 1176 1177 hw = sw->hw;1178 if (sw->active != on){1179 SWVoiceOut *temp_sw;2089 2090 hw = sw->pHostVoiceOut; 2091 if (sw->State.fActive != on) 2092 { 2093 PPDMGSTVOICEOUT pIter; 1180 2094 SWVoiceCap *sc; 1181 1182 if (on) { 2095 SWVoiceCap *pIterCap; 2096 2097 if (on) 2098 { 1183 2099 hw->pending_disable = 0; 1184 if (!hw->enabled) { 1185 hw->enabled = 1; 1186 hw->pcm_ops->ctl_out (hw, VOICE_ENABLE); 2100 if (!hw->fEnabled) 2101 { 2102 hw->fEnabled = 1; 2103 pThis->pHostDrvAudio->pfnDisableEnableOut(pThis->pHostDrvAudio, hw, VOICE_ENABLE); 1187 2104 } 1188 2105 } 1189 else { 1190 if (hw->enabled) { 2106 else 2107 { 2108 if (hw->fEnabled) 2109 { 1191 2110 int nb_active = 0; 1192 2111 1193 for (temp_sw = hw->sw_head.lh_first; temp_sw;1194 temp_sw = temp_sw->entries.le_next){1195 nb_active += temp_sw->active != 0;2112 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 2113 { 2114 nb_active += pIter->State.fActive != 0; 1196 2115 } 1197 2116 … … 1200 2119 } 1201 2120 1202 for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) { 1203 sc->sw.active = hw->enabled; 1204 if (hw->enabled) { 2121 RTListForEach(&hw->HeadCapturedVoice, pIterCap, SWVoiceCap, ListCapturedVoice) 2122 { 2123 sc = pIterCap; 2124 sc->sw.State.fActive = hw->fEnabled; 2125 if (hw->fEnabled) { 1205 2126 audio_capture_maybe_changed (sc->cap, 1); 1206 2127 } 1207 2128 } 1208 sw-> active = on;1209 } 1210 } 1211 1212 void AUD_set_active_in (SWVoiceIn *sw, int on)1213 { 1214 HWVoiceIn *hw;1215 2129 sw->State.fActive = on; 2130 } 2131 } 2132 2133 static DECLCALLBACK(void) drvAudioEnableIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN sw , int on) 2134 { 2135 PPDMHOSTVOICEIN hw; 2136 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1216 2137 if (!sw) { 2138 LogFlow(("DrvAudio: NO GuestVoiceIn. Returning 0\n")); 1217 2139 return; 1218 2140 } 1219 2141 1220 2142 hw = sw->hw; 1221 if (sw->active != on) { 1222 SWVoiceIn *temp_sw; 1223 1224 if (on) { 1225 if (!hw->enabled) { 2143 if (sw->State.fActive != on) 2144 { 2145 PPDMGSTVOICEIN pIter; 2146 2147 if (on) 2148 { 2149 if (!hw->enabled) 2150 { 1226 2151 hw->enabled = 1; 1227 hw->pcm_ops->ctl_in (hw, VOICE_ENABLE);2152 pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hw, VOICE_ENABLE); 1228 2153 } 1229 sw->total_hw_samples_acquired = hw->total_samples_captured; 1230 } 1231 else { 1232 if (hw->enabled) { 2154 sw->cHostSamplesAcquired = hw->cSamplesCaptured; 2155 } 2156 else 2157 { 2158 if (hw->enabled) 2159 { 1233 2160 int nb_active = 0; 1234 2161 1235 for (temp_sw = hw->sw_head.lh_first; temp_sw;1236 temp_sw = temp_sw->entries.le_next){1237 nb_active += temp_sw->active != 0;2162 RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn) 2163 { 2164 nb_active += pIter->State.fActive != 0; 1238 2165 } 1239 2166 1240 2167 if (nb_active == 1) { 1241 2168 hw->enabled = 0; 1242 hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);2169 pThis->pHostDrvAudio->pfnDisableEnableIn(pThis->pHostDrvAudio, hw, VOICE_DISABLE); 1243 2170 } 1244 2171 } 1245 2172 } 1246 sw->active = on; 1247 } 1248 } 1249 1250 static int audio_get_avail (SWVoiceIn *sw) 1251 { 1252 int live; 1253 1254 if (!sw) { 1255 return 0; 1256 } 1257 1258 live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired; 1259 if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) { 1260 dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples); 1261 return 0; 1262 } 1263 1264 ldebug ( 1265 "%s: get_avail live %d ret %lld\n", 1266 SW_NAME (sw), 1267 live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift 1268 ); 1269 1270 return (((int64_t) live << 32) / sw->ratio) << sw->info.shift; 1271 } 1272 1273 static int audio_get_free (SWVoiceOut *sw) 1274 { 1275 int live, dead; 1276 1277 if (!sw) { 1278 return 0; 1279 } 1280 1281 live = sw->total_hw_samples_mixed; 1282 1283 if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) { 1284 dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples); 1285 return 0; 1286 } 1287 1288 dead = sw->hw->samples - live; 1289 1290 #ifdef DEBUG_OUT 1291 dolog ("%s: get_free live %d dead %d ret %lld\n", 1292 SW_NAME (sw), 1293 live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift); 1294 #endif 1295 1296 return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift; 1297 } 1298 1299 static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples) 1300 { 1301 int n; 1302 1303 if (hw->enabled) { 1304 SWVoiceCap *sc; 1305 1306 for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) { 1307 SWVoiceOut *sw = &sc->sw; 1308 int rpos2 = rpos; 1309 1310 n = samples; 1311 while (n) { 1312 int till_end_of_hw = hw->samples - rpos2; 1313 int to_write = audio_MIN (till_end_of_hw, n); 1314 int bytes = to_write << hw->info.shift; 1315 int written; 1316 1317 sw->buf = hw->mix_buf + rpos2; 1318 written = audio_pcm_sw_write (sw, NULL, bytes); 1319 if (written - bytes) { 1320 dolog ("Could not mix %d bytes into a capture " 1321 "buffer, mixed %d\n", 1322 bytes, written); 1323 break; 1324 } 1325 n -= to_write; 1326 rpos2 = (rpos2 + to_write) % hw->samples; 1327 } 1328 } 1329 } 1330 1331 n = audio_MIN (samples, hw->samples - rpos); 1332 mixeng_sniff_and_clear (hw, hw->mix_buf + rpos, n); 1333 mixeng_sniff_and_clear (hw, hw->mix_buf, samples - n); 1334 } 1335 1336 static void audio_run_out (AudioState *s) 1337 { 1338 HWVoiceOut *hw = NULL; 1339 SWVoiceOut *sw; 1340 1341 while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) { 1342 int played; 1343 int live, myfree, nb_live, cleanup_required, prev_rpos; 1344 1345 live = audio_pcm_hw_get_live_out2 (hw, &nb_live); 1346 if (!nb_live) { 1347 live = 0; 1348 } 1349 1350 if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) { 1351 dolog ("live=%d hw->samples=%d\n", live, hw->samples); 1352 continue; 1353 } 1354 1355 if (hw->pending_disable && !nb_live) { 1356 SWVoiceCap *sc; 1357 #ifdef DEBUG_OUT 1358 dolog ("Disabling voice\n"); 1359 #endif 1360 hw->enabled = 0; 1361 hw->pending_disable = 0; 1362 hw->pcm_ops->ctl_out (hw, VOICE_DISABLE); 1363 for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) { 1364 sc->sw.active = 0; 1365 audio_recalc_and_notify_capture (sc->cap); 1366 } 1367 continue; 1368 } 1369 1370 if (!live) { 1371 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 1372 if (sw->active) { 1373 myfree = audio_get_free (sw); 1374 if (myfree > 0) { 1375 sw->callback.fn (sw->callback.opaque, myfree); 1376 } 1377 } 1378 } 1379 continue; 1380 } 1381 1382 prev_rpos = hw->rpos; 1383 played = hw->pcm_ops->run_out (hw); 1384 if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) { 1385 dolog ("hw->rpos=%d hw->samples=%d played=%d\n", 1386 hw->rpos, hw->samples, played); 1387 hw->rpos = 0; 1388 } 1389 1390 #ifdef DEBUG_OUT 1391 dolog ("played=%d\n", played); 1392 #endif 1393 1394 if (played) { 1395 hw->ts_helper += played; 1396 audio_capture_mix_and_clear (hw, prev_rpos, played); 1397 } 1398 1399 cleanup_required = 0; 1400 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 1401 if (!sw->active && sw->empty) { 1402 continue; 1403 } 1404 1405 if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) { 1406 dolog ("played=%d sw->total_hw_samples_mixed=%d\n", 1407 played, sw->total_hw_samples_mixed); 1408 played = sw->total_hw_samples_mixed; 1409 } 1410 1411 sw->total_hw_samples_mixed -= played; 1412 1413 if (!sw->total_hw_samples_mixed) { 1414 sw->empty = 1; 1415 cleanup_required |= !sw->active && !sw->callback.fn; 1416 } 1417 1418 if (sw->active) { 1419 myfree = audio_get_free (sw); 1420 if (myfree > 0) { 1421 sw->callback.fn (sw->callback.opaque, myfree); 1422 } 1423 } 1424 } 1425 1426 if (cleanup_required) { 1427 SWVoiceOut *sw1; 1428 1429 sw = hw->sw_head.lh_first; 1430 while (sw) { 1431 sw1 = sw->entries.le_next; 1432 if (!sw->active && !sw->callback.fn) { 1433 #ifdef DEBUG_PLIVE 1434 dolog ("Finishing with old voice\n"); 1435 #endif 1436 audio_close_out (s, sw); 1437 } 1438 sw = sw1; 1439 } 1440 } 1441 } 1442 } 1443 1444 static void audio_run_in (AudioState *s) 1445 { 1446 HWVoiceIn *hw = NULL; 1447 1448 while ((hw = audio_pcm_hw_find_any_enabled_in (s, hw))) { 1449 SWVoiceIn *sw; 1450 int captured, min; 1451 1452 captured = hw->pcm_ops->run_in (hw); 1453 1454 min = audio_pcm_hw_find_min_in (hw); 1455 hw->total_samples_captured += captured - min; 1456 hw->ts_helper += captured; 1457 1458 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 1459 sw->total_hw_samples_acquired -= min; 1460 1461 if (sw->active) { 1462 int avail; 1463 1464 avail = audio_get_avail (sw); 1465 if (avail > 0) { 1466 sw->callback.fn (sw->callback.opaque, avail); 1467 } 1468 } 1469 } 1470 } 1471 } 1472 1473 static void audio_run_capture (AudioState *s) 1474 { 1475 CaptureVoiceOut *cap; 1476 1477 for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) { 1478 int live, rpos, captured; 1479 HWVoiceOut *hw = &cap->hw; 1480 SWVoiceOut *sw; 1481 1482 captured = live = audio_pcm_hw_get_live_out (hw); 1483 rpos = hw->rpos; 1484 while (live) { 1485 int left = hw->samples - rpos; 1486 int to_capture = audio_MIN (live, left); 1487 st_sample_t *src; 1488 struct capture_callback *cb; 1489 1490 src = hw->mix_buf + rpos; 1491 hw->clip (cap->buf, src, to_capture); 1492 mixeng_sniff_and_clear (hw, src, to_capture); 1493 1494 for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) { 1495 cb->ops.capture (cb->opaque, cap->buf, 1496 to_capture << hw->info.shift); 1497 } 1498 rpos = (rpos + to_capture) % hw->samples; 1499 live -= to_capture; 1500 } 1501 hw->rpos = rpos; 1502 1503 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) { 1504 if (!sw->active && sw->empty) { 1505 continue; 1506 } 1507 1508 if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) { 1509 dolog ("captured=%d sw->total_hw_samples_mixed=%d\n", 1510 captured, sw->total_hw_samples_mixed); 1511 captured = sw->total_hw_samples_mixed; 1512 } 1513 1514 sw->total_hw_samples_mixed -= captured; 1515 sw->empty = sw->total_hw_samples_mixed == 0; 1516 } 1517 } 1518 } 1519 1520 static void audio_timer (void *opaque) 1521 { 1522 AudioState *s = opaque; 1523 1524 audio_run_out (s); 1525 audio_run_in (s); 1526 audio_run_capture (s); 1527 1528 TMTimerSet (s->ts, TMTimerGet (s->ts) + conf.period.ticks); 1529 } 1530 1531 static struct audio_option audio_options[] = { 1532 /* DAC */ 1533 {"DACFixedSettings", AUD_OPT_BOOL, &conf.fixed_out.enabled, 1534 "Use fixed settings for host DAC", NULL, 0}, 1535 1536 {"DACFixedFreq", AUD_OPT_INT, &conf.fixed_out.settings.freq, 1537 "Frequency for fixed host DAC", NULL, 0}, 1538 1539 {"DACFixedFmt", AUD_OPT_FMT, &conf.fixed_out.settings.fmt, 1540 "Format for fixed host DAC", NULL, 0}, 1541 1542 {"DACFixedChannels", AUD_OPT_INT, &conf.fixed_out.settings.nchannels, 1543 "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0}, 1544 1545 {"DACVoices", AUD_OPT_INT, &conf.fixed_out.nb_voices, 1546 "Number of voices for DAC", NULL, 0}, 1547 1548 /* ADC */ 1549 {"ADCFixedSettings", AUD_OPT_BOOL, &conf.fixed_in.enabled, 1550 "Use fixed settings for host ADC", NULL, 0}, 1551 1552 {"ADCFixedFreq", AUD_OPT_INT, &conf.fixed_in.settings.freq, 1553 "Frequency for fixed host ADC", NULL, 0}, 1554 1555 {"ADCFixedFmt", AUD_OPT_FMT, &conf.fixed_in.settings.fmt, 1556 "Format for fixed host ADC", NULL, 0}, 1557 1558 {"ADCFixedChannels", AUD_OPT_INT, &conf.fixed_in.settings.nchannels, 1559 "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0}, 1560 1561 {"ADCVoices", AUD_OPT_INT, &conf.fixed_in.nb_voices, 1562 "Number of voices for ADC", NULL, 0}, 1563 1564 /* Misc */ 1565 {"TimerFreq", AUD_OPT_INT, &conf.period.hz, 1566 "Timer frequency in Hz (0 - use lowest possible)", NULL, 0}, 1567 1568 {"PLIVE", AUD_OPT_BOOL, &conf.plive, 1569 "(undocumented)", NULL, 0}, 1570 1571 {NULL, 0, NULL, NULL, NULL, 0} 1572 }; 1573 1574 static int audio_driver_init (PCFGMNODE pCfgHandle, AudioState *s, struct audio_driver *drv) 1575 { 1576 if (drv->options) { 1577 audio_process_options (pCfgHandle, drv->name, drv->options); 1578 } 1579 s->drv_opaque = drv->init (); 1580 1581 if (s->drv_opaque) { 1582 /* Filter must be installed before initializing voices. */ 1583 drv = filteraudio_install(drv, s->drv_opaque); 1584 audio_init_nb_voices_out (s, drv); 1585 audio_init_nb_voices_in (s, drv); 1586 s->drv = drv; 1587 return 0; 1588 } 1589 else { 1590 dolog ("Could not init `%s' audio driver\n", drv->name); 1591 return -1; 1592 } 1593 } 1594 1595 static void audio_vm_change_state_handler (void *opaque, int running) 1596 { 1597 AudioState *s = opaque; 1598 HWVoiceOut *hwo = NULL; 1599 HWVoiceIn *hwi = NULL; 1600 int op = running ? VOICE_ENABLE : VOICE_DISABLE; 1601 1602 while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) { 1603 hwo->pcm_ops->ctl_out (hwo, op); 1604 } 1605 1606 while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) { 1607 hwi->pcm_ops->ctl_in (hwi, op); 1608 } 1609 } 1610 1611 static void audio_atexit (void) 1612 { 1613 AudioState *s = &glob_audio_state; 1614 HWVoiceOut *hwo = NULL; 1615 HWVoiceIn *hwi = NULL; 1616 1617 /* VBox change: audio_pcm_hw_find_any_enabled_out => audio_pcm_hw_find_any_out */ 1618 while ((hwo = audio_pcm_hw_find_any_out (s, hwo))) { 1619 SWVoiceCap *sc; 1620 1621 hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE); 1622 hwo->pcm_ops->fini_out (hwo); 1623 1624 for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) { 1625 CaptureVoiceOut *cap = sc->cap; 1626 struct capture_callback *cb; 1627 1628 for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) { 1629 cb->ops.destroy (cb->opaque); 1630 } 1631 } 1632 } 1633 1634 /* VBox change: audio_pcm_hw_find_any_enabled_in => audio_pcm_hw_find_any_in */ 1635 while ((hwi = audio_pcm_hw_find_any_in (s, hwi))) { 1636 hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE); 1637 hwi->pcm_ops->fini_in (hwi); 1638 } 1639 1640 if (s->drv) { 1641 s->drv->fini (s->drv_opaque); 1642 } 1643 } 1644 1645 void AUD_register_card (const char *name, QEMUSoundCard *card) 1646 { 1647 AudioState *s = &glob_audio_state; 1648 card->audio = s; 1649 card->name = qemu_strdup (name); 1650 memset (&card->entries, 0, sizeof (card->entries)); 1651 LIST_INSERT_HEAD (&s->card_head, card, entries); 1652 } 1653 1654 void AUD_remove_card (QEMUSoundCard *card) 1655 { 1656 LIST_REMOVE (card, entries); 1657 card->audio = NULL; 1658 qemu_free (card->name); 1659 } 1660 1661 static DECLCALLBACK(void) audio_timer_helper (PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser) 1662 { 1663 AudioState *s = (AudioState *)pvUser; 1664 audio_timer (s); 1665 } 1666 1667 static int AUD_init (PCFGMNODE pCfgHandle, PPDMDRVINS pDrvIns, const char *drvname) 1668 { 1669 size_t i; 1670 int done = 0; 1671 AudioState *s = &glob_audio_state; 1672 int rc; 1673 1674 LIST_INIT (&s->hw_head_out); 1675 LIST_INIT (&s->hw_head_in); 1676 LIST_INIT (&s->cap_head); 1677 1678 rc = PDMDrvHlpTMTimerCreate (pDrvIns, TMCLOCK_VIRTUAL, audio_timer_helper, 1679 &glob_audio_state, 0, "Audio timer", &s->ts); 1680 if (RT_FAILURE (rc)) 1681 return rc; 1682 1683 audio_process_options (pCfgHandle, "AUDIO", audio_options); 1684 1685 s->nb_hw_voices_out = conf.fixed_out.nb_voices; 1686 s->nb_hw_voices_in = conf.fixed_in.nb_voices; 1687 1688 if (s->nb_hw_voices_out <= 0) { 1689 dolog ("Bogus number of playback voices %d, setting to 1\n", 1690 s->nb_hw_voices_out); 1691 s->nb_hw_voices_out = 1; 1692 } 1693 1694 if (s->nb_hw_voices_in <= 0) { 1695 dolog ("Bogus number of capture voices %d, setting to 0\n", 1696 s->nb_hw_voices_in); 1697 s->nb_hw_voices_in = 0; 1698 } 1699 1700 LogRel(("Audio: Trying driver '%s'.\n", drvname)); 1701 1702 if (drvname) { 1703 int found = 0; 1704 1705 for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) { 1706 if (!strcmp (drvname, drvtab[i]->name)) { 1707 done = !audio_driver_init (pCfgHandle, s, drvtab[i]); 1708 found = 1; 1709 break; 1710 } 1711 } 1712 1713 if (!found) { 1714 dolog ("Unknown audio driver `%s'\n", drvname); 1715 } 1716 } 1717 1718 if (!done) { 1719 for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) { 1720 if (drvtab[i]->can_be_default) { 1721 LogRel(("Audio: Initialization of driver '%s' failed, trying '%s'.\n", 1722 drvname, drvtab[i]->name)); 1723 drvname = drvtab[i]->name; 1724 done = !audio_driver_init (pCfgHandle, s, drvtab[i]); 1725 } 1726 } 1727 } 1728 1729 if (!done) { 1730 done = !audio_driver_init (pCfgHandle, s, &no_audio_driver); 1731 if (!done) { 1732 dolog ("Could not initialize audio subsystem\n"); 1733 } 1734 else { 1735 LogRel(("Audio: Initialization of driver '%s' failed, using NULL driver.\n", drvname)); 1736 dolog ("warning: Using timer based audio emulation\n"); 1737 } 1738 } 1739 1740 if (done) { 1741 if (conf.period.hz <= 0) { 1742 if (conf.period.hz < 0) { 1743 dolog ("warning: Timer period is negative - %d " 1744 "treating as zero\n", 1745 conf.period.hz); 1746 } 1747 conf.period.ticks = 1; 1748 } 1749 else { 1750 conf.period.ticks = PDMDrvHlpTMGetVirtualFreq (pDrvIns) 1751 / conf.period.hz; 1752 } 1753 } 1754 else { 1755 /* XXX */ 1756 rc = TMR3TimerDestroy (s->ts); 1757 return rc; 1758 } 1759 1760 LIST_INIT (&s->card_head); 1761 TMTimerSet (s->ts, TMTimerGet (s->ts) + conf.period.ticks); 1762 return VINF_SUCCESS; 1763 } 1764 1765 int AUD_init_null(void) 1766 { 1767 AudioState *s = &glob_audio_state; 1768 1769 #ifdef VBOX 1770 if (s->drv) 1771 s->drv->fini (s->drv_opaque); 1772 #endif 1773 1774 LogRel(("Audio: Using NULL audio driver\n")); 1775 return audio_driver_init (NULL, s, &no_audio_driver); 1776 } 1777 1778 CaptureVoiceOut *AUD_add_capture ( 1779 AudioState *s, 1780 audsettings_t *as, 1781 struct audio_capture_ops *ops, 1782 void *cb_opaque 1783 ) 1784 { 1785 CaptureVoiceOut *cap; 1786 struct capture_callback *cb; 1787 1788 if (!s) { 1789 /* XXX suppress */ 1790 s = &glob_audio_state; 1791 } 1792 1793 if (audio_validate_settings (as)) { 1794 dolog ("Invalid settings were passed when trying to add capture\n"); 1795 audio_print_settings (as); 1796 goto err0; 1797 } 1798 1799 cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb)); 1800 if (!cb) { 1801 dolog ("Could not allocate capture callback information, size %u\n", 1802 sizeof (*cb)); 1803 goto err0; 1804 } 1805 cb->ops = *ops; 1806 cb->opaque = cb_opaque; 1807 1808 cap = audio_pcm_capture_find_specific (s, as); 1809 if (cap) { 1810 LIST_INSERT_HEAD (&cap->cb_head, cb, entries); 1811 return cap; 1812 } 1813 else { 1814 HWVoiceOut *hw; 1815 #ifndef VBOX 1816 CaptureVoiceOut *cap; 1817 #endif 1818 1819 cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap)); 1820 if (!cap) { 1821 dolog ("Could not allocate capture voice, size %u\n", 1822 sizeof (*cap)); 1823 goto err1; 1824 } 1825 1826 hw = &cap->hw; 1827 LIST_INIT (&hw->sw_head); 1828 LIST_INIT (&cap->cb_head); 1829 1830 /* XXX find a more elegant way */ 1831 hw->samples = 4096 * 4; 1832 hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1833 sizeof (st_sample_t)); 1834 if (!hw->mix_buf) { 1835 dolog ("Could not allocate capture mix buffer (%d samples)\n", 1836 hw->samples); 1837 goto err2; 1838 } 1839 1840 audio_pcm_init_info (&hw->info, as); 1841 1842 cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 1843 if (!cap->buf) { 1844 dolog ("Could not allocate capture buffer " 1845 "(%d samples, each %d bytes)\n", 1846 hw->samples, 1 << hw->info.shift); 1847 goto err3; 1848 } 1849 1850 hw->clip = mixeng_clip 1851 [hw->info.nchannels == 2] 1852 [hw->info.sign] 1853 [hw->info.swap_endianness] 1854 [audio_bits_to_index (hw->info.bits)]; 1855 1856 LIST_INSERT_HEAD (&s->cap_head, cap, entries); 1857 LIST_INSERT_HEAD (&cap->cb_head, cb, entries); 1858 1859 hw = NULL; 1860 while ((hw = audio_pcm_hw_find_any_out (s, hw))) { 1861 audio_attach_capture (s, hw); 1862 } 1863 return cap; 1864 1865 err3: 1866 qemu_free (cap->hw.mix_buf); 1867 err2: 1868 qemu_free (cap); 1869 err1: 1870 qemu_free (cb); 1871 err0: 1872 return NULL; 1873 } 1874 } 1875 1876 void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque) 1877 { 1878 struct capture_callback *cb; 1879 1880 for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) { 1881 if (cb->opaque == cb_opaque) { 1882 cb->ops.destroy (cb_opaque); 1883 LIST_REMOVE (cb, entries); 1884 qemu_free (cb); 1885 1886 if (!cap->cb_head.lh_first) { 1887 SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1; 1888 1889 while (sw) { 1890 SWVoiceCap *sc = (SWVoiceCap *) sw; 1891 #ifdef DEBUG_CAPTURE 1892 dolog ("freeing %s\n", sw->name); 1893 #endif 1894 1895 sw1 = sw->entries.le_next; 1896 if (sw->rate) { 1897 st_rate_stop (sw->rate); 1898 sw->rate = NULL; 1899 } 1900 LIST_REMOVE (sw, entries); 1901 LIST_REMOVE (sc, entries); 1902 qemu_free (sc); 1903 sw = sw1; 1904 } 1905 LIST_REMOVE (cap, entries); 1906 qemu_free (cap); 1907 } 1908 return; 1909 } 1910 } 1911 } 1912 1913 void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol) 1914 { 1915 if (sw) 1916 { 1917 sw->vol.mute = mute; 1918 sw->vol.l = (uint32_t)lvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */ 1919 sw->vol.r = (uint32_t)rvol * 0x808080; /* maximum is INT_MAX = 0x7fffffff */ 1920 } 1921 } 1922 1923 void AUD_set_volume (audmixerctl_t mt, int *mute, uint8_t *lvol, uint8_t *rvol) 1924 { 1925 volume_t *vol = NULL; 1926 const char *name; 1927 1928 switch (mt) 1929 { 1930 case AUD_MIXER_VOLUME: 1931 name = "MASTER"; 1932 vol = &master_out_volume; 1933 break; 1934 case AUD_MIXER_PCM: 1935 name = "PCM_OUT"; 1936 vol = &pcm_out_volume; 1937 break; 1938 case AUD_MIXER_LINE_IN: 1939 name = "LINE_IN"; 1940 vol = &pcm_in_volume; 1941 break; 1942 default: 1943 return; 1944 1945 } 1946 1947 if (vol) 1948 { 1949 uint32_t u32VolumeLeft = (uint32_t)*lvol; 1950 uint32_t u32VolumeRight = (uint32_t)*rvol; 1951 /* 0x00..0xff => 0x01..0x100 */ 1952 if (u32VolumeLeft) 1953 u32VolumeLeft++; 1954 if (u32VolumeRight) 1955 u32VolumeRight++; 1956 vol->mute = *mute; 1957 vol->l = u32VolumeLeft * 0x800000; /* maximum is 0x80000000 */ 1958 vol->r = u32VolumeRight * 0x800000; /* maximum is 0x80000000 */ 1959 } 1960 sum_out_volume.mute = master_out_volume.mute || pcm_out_volume.mute; 1961 sum_out_volume.l = ASMMultU64ByU32DivByU32(master_out_volume.l, pcm_out_volume.l, 0x80000000U); 1962 sum_out_volume.r = ASMMultU64ByU32DivByU32(master_out_volume.r, pcm_out_volume.r, 0x80000000U); 1963 } 1964 1965 void AUD_set_record_source (audrecsource_t *ars, audrecsource_t *als) 1966 { 1967 LogRel(("Audio: set_record_source ars=%d als=%d (not implemented)\n", *ars, *als)); 1968 } 1969 1970 int AUD_is_host_voice_in_ok(SWVoiceIn *sw) 1971 { 1972 AudioState *s = &glob_audio_state; 1973 2173 sw->State.fActive = on; 2174 } 2175 } 2176 2177 static DECLCALLBACK(int) drvAudioIsHostVoiceInOK(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN sw) 2178 { 1974 2179 if (sw == NULL) { 1975 2180 return 0; 1976 2181 } 1977 1978 return filteraudio_is_host_voice_in_ok(s->drv, sw->hw); 1979 } 1980 1981 int AUD_is_host_voice_out_ok(SWVoiceOut *sw) 1982 { 1983 AudioState *s = &glob_audio_state; 1984 2182 return 1; 2183 } 2184 2185 static DECLCALLBACK(int) drvAudioIsHostVoiceOutOK(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT sw) 2186 { 1985 2187 if (sw == NULL) { 1986 2188 return 0; 1987 2189 } 1988 1989 return filteraudio_is_host_voice_out_ok(s->drv, sw->hw); 1990 } 2190 return 1; 2191 } 2192 2193 static DECLCALLBACK(int) drvAudioOpenIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN *ppGstVoiceIn, 2194 const char *name, void *callback_opaque , audio_callback_fn_t callback_fn, 2195 uint32_t uFrequency, uint32_t cChannels, audfmt_e Format, uint32_t Endian) 2196 { 2197 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2198 audsettings_t AudioSettings; 2199 AudioSettings.freq = uFrequency; 2200 AudioSettings.nchannels = cChannels; 2201 AudioSettings.fmt = Format; 2202 AudioSettings.endianness = Endian; 2203 LogFlow(("DrvAudio: open IN %s, freq %d, nchannels %d, fmt %d\n", 2204 name, AudioSettings.freq, AudioSettings.nchannels, AudioSettings.fmt)); 2205 2206 if (drvAudioValidateSettings(&AudioSettings)) 2207 { 2208 LogRel(("Audio: Audio Settings Validation failed \n")); 2209 drvAudioPrintSettings(&AudioSettings); 2210 drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn); 2211 *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL; 2212 return VERR_GENERAL_FAILURE; 2213 } 2214 2215 if (*ppGstVoiceIn && drvAudioPcmInfoEq(&(*ppGstVoiceIn)->Props, &AudioSettings)) 2216 return VINF_SUCCESS; 2217 2218 if (!conf.fixed_in.enabled && *ppGstVoiceIn) 2219 { 2220 drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn); 2221 *ppGstVoiceIn = (PPDMGSTVOICEIN )NULL; 2222 } 2223 2224 if (*ppGstVoiceIn) 2225 { 2226 PPDMHOSTVOICEIN pHostVoiceIn = (*ppGstVoiceIn)->hw; 2227 2228 if (!pHostVoiceIn) 2229 { 2230 LogFlow(("Internal logic error voice has no hardware store\n")); 2231 drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn); 2232 *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL; 2233 return VERR_GENERAL_FAILURE; 2234 } 2235 2236 drvAudioHlpPcmSwFinishedIn(*ppGstVoiceIn); 2237 if (drvAudioHlpPcmSwInitIn(*ppGstVoiceIn, pHostVoiceIn, name, &AudioSettings)) 2238 { 2239 drvAudioHlpCloseIn(pThis, &pThis->qemuSoundCard, *ppGstVoiceIn); 2240 *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL; 2241 return VERR_GENERAL_FAILURE; 2242 } 2243 } 2244 else 2245 { 2246 *ppGstVoiceIn = drvAudioHlpPcmCreateVoicePairIn(pThis, name, &AudioSettings); 2247 if (!(*ppGstVoiceIn)) 2248 { 2249 LogFlow(("Failed to create voice `%s'\n", name)); 2250 *ppGstVoiceIn = (PPDMGSTVOICEIN)NULL; 2251 return VERR_GENERAL_FAILURE; 2252 } 2253 } 2254 2255 if (*ppGstVoiceIn) 2256 { 2257 (*ppGstVoiceIn)->State.uVolumeLeft = nominal_volume.l; 2258 (*ppGstVoiceIn)->State.uVolumeRight = nominal_volume.r; 2259 (*ppGstVoiceIn)->State.uVolumeMute = nominal_volume.mute; 2260 (*ppGstVoiceIn)->callback.fn = callback_fn; 2261 (*ppGstVoiceIn)->callback.opaque = callback_opaque; 2262 } 2263 return VINF_SUCCESS; 2264 } 2265 2266 2267 static DECLCALLBACK(int) drvAudioOpenOut(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT *ppGstVoiceOut, const char *name, 2268 void *callback_opaque, audio_callback_fn_t callback_fn, 2269 uint32_t uFrequency, uint32_t cChannels, audfmt_e Format, uint32_t Endian) 2270 { 2271 int cLiveSamples = 0; 2272 AudioState *s; 2273 int rc; 2274 PPDMGSTVOICEOUT pOldGstVoiceOut; 2275 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2276 audsettings_t AudioSettings; 2277 AudioSettings.freq = uFrequency; 2278 AudioSettings.nchannels = cChannels; 2279 AudioSettings.fmt = Format; 2280 AudioSettings.endianness = Endian; 2281 2282 LogFlow(("DrvAudio: open OUT %s, freq %d, nchannels %d, fmt %d\n", 2283 name, AudioSettings.freq, AudioSettings.nchannels, AudioSettings.fmt)); 2284 2285 if (drvAudioValidateSettings(&AudioSettings)) 2286 { 2287 LogRel(("DrvAudio: Audio Settings Validation failed \n")); 2288 drvAudioPrintSettings(&AudioSettings); 2289 drvAudioHlpCloseOut(pThis, &pThis->qemuSoundCard, *ppGstVoiceOut); 2290 *ppGstVoiceOut = (PPDMGSTVOICEOUT)NULL; 2291 return VERR_GENERAL_FAILURE; 2292 } 2293 2294 if (*ppGstVoiceOut && drvAudioPcmInfoEq(&(*ppGstVoiceOut)->Props, &AudioSettings)) 2295 return VINF_SUCCESS; 2296 2297 if ( conf.plive && *ppGstVoiceOut 2298 && (!(*ppGstVoiceOut)->State.fActive 2299 && !(*ppGstVoiceOut)->State.fEmpty) 2300 ) 2301 { 2302 cLiveSamples = (*ppGstVoiceOut)->cSamplesMixed; 2303 if(cLiveSamples) 2304 { 2305 pOldGstVoiceOut = *ppGstVoiceOut; 2306 *ppGstVoiceOut = NULL; 2307 } 2308 } 2309 2310 if (!conf.fixed_out.enabled && *ppGstVoiceOut) 2311 { 2312 drvAudioHlpCloseOut(pThis, &pThis->qemuSoundCard, *ppGstVoiceOut); 2313 *ppGstVoiceOut = (PPDMGSTVOICEOUT *)NULL; 2314 } 2315 2316 if (*ppGstVoiceOut) 2317 { 2318 PPDMHOSTVOICEOUT pHostVoiceOut = (*ppGstVoiceOut)->pHostVoiceOut; 2319 if (!pHostVoiceOut) 2320 { 2321 LogFlow(("Guest Voice Stream has no Host voice stream in store\n")); 2322 return VERR_GENERAL_FAILURE; 2323 } 2324 2325 drvAudioHlpPcmSwFinishedOut(*ppGstVoiceOut); 2326 rc = drvAudioHlpPcmSwInitOut(*ppGstVoiceOut, pHostVoiceOut, name, &AudioSettings); 2327 if (RT_FAILURE(rc)) 2328 return rc; 2329 } 2330 else 2331 { 2332 (*ppGstVoiceOut) = drvAudioHlpPcmCreateVoicePairOut(pThis, s, name, &AudioSettings); 2333 if (!(*ppGstVoiceOut)) 2334 { 2335 LogFlow(("Failed to create voice `%s'\n", name)); 2336 *ppGstVoiceOut = (PPDMGSTVOICEOUT)NULL; 2337 return VERR_GENERAL_FAILURE; 2338 } 2339 } 2340 2341 if (*ppGstVoiceOut) 2342 { 2343 (*ppGstVoiceOut)->State.uVolumeLeft = nominal_volume.l; 2344 (*ppGstVoiceOut)->State.uVolumeRight = nominal_volume.r; 2345 (*ppGstVoiceOut)->State.uVolumeMute = nominal_volume.mute; 2346 (*ppGstVoiceOut)->callback.fn = callback_fn; 2347 (*ppGstVoiceOut)->callback.opaque = callback_opaque; 2348 if (cLiveSamples) 2349 { 2350 int mixed = 2351 (cLiveSamples << pOldGstVoiceOut->Props.cShift) 2352 * pOldGstVoiceOut->Props.cbPerSec 2353 / (*ppGstVoiceOut)->Props.cbPerSec; 2354 2355 (*ppGstVoiceOut)->cSamplesMixed += mixed; 2356 } 2357 } 2358 2359 return VINF_SUCCESS; 2360 } 2361 2362 static DECLCALLBACK(int) drvAudioIsActiveIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN pGstVoiceIn) 2363 { 2364 return pGstVoiceIn ? pGstVoiceIn->State.fActive : 0; 2365 } 2366 2367 static DECLCALLBACK(int) drvAudioIsActiveOut(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT pGstVoiceOut) 2368 { 2369 return pGstVoiceOut ? pGstVoiceOut->State.fActive : 0; 2370 } 2371 2372 static DECLCALLBACK(t_sample *)drvAudioConvDevFmtToStSample(PPDMIAUDIOCONNECTOR pInterface, uint32_t cChannels, 2373 uint32_t fSign, uint32_t uEndian, uint32_t ubitIdx) 2374 { 2375 LogFlow(("DrvAudio: drvAudioConvStSamplToFmt \n")); 2376 return mixeng_conv[cChannels] /* stereo */ 2377 [fSign] /* sign */ 2378 [uEndian] /* big endian */ 2379 [ubitIdx]; /* bits */ 2380 2381 } 2382 2383 static DECLCALLBACK(f_sample *)drvAudioConvStSampleToDevFmt(PPDMIAUDIOCONNECTOR pInterface, void *buf, 2384 PPDMHOSTSTEREOSAMPLE pSampleBuf, uint32_t samples) 2385 { 2386 /*@todo handle ths properly*/ 2387 clipAudioIn (buf, pSampleBuf, samples); 2388 } 2389 2390 2391 static DECLCALLBACK(void *)drvAudioPrepareAudioConversion(PPDMIAUDIOCONNECTOR pInterface, uint32_t uSampleFreq, uint32_t uTgtFreq) 2392 { 2393 return st_rate_start (uSampleFreq, uTgtFreq); 2394 } 2395 2396 static DECLCALLBACK(void)drvAudioEndAudioConversion(PPDMIAUDIOCONNECTOR pInterface, void * pRate) 2397 { 2398 AssertPtr(pRate); 2399 st_rate_stop (pRate); 2400 } 2401 2402 static DECLCALLBACK(void)drvAudioDoRateConversion(PPDMIAUDIOCONNECTOR pInterface, void * pRate, 2403 PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf, 2404 PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf, 2405 uint32_t * pcSampleSrc, uint32_t *pcConvertedSamples) 2406 { 2407 AssertPtr(pRate); 2408 st_rate_flow(pRate, pHostStereoSampleBuf, pConvertedSampleBuf, pcSampleSrc, pcConvertedSamples); 2409 2410 } 2411 2412 static DECLCALLBACK(void)drvAudioDoRateConvAndMix(PPDMIAUDIOCONNECTOR pInterface, void * pRate, 2413 PPDMHOSTSTEREOSAMPLE pSourceSampleBuf, 2414 PPDMHOSTSTEREOSAMPLE pTargetMixedSampleBuf, 2415 uint32_t * pcSampleSrc, uint32_t *pcMixedSamples) 2416 { 2417 st_rate_flow_mix(pRate, pSourceSampleBuf, pTargetMixedSampleBuf, pcSampleSrc, pcMixedSamples); 2418 2419 } 2420 2421 /****************************************************************/ 2422 2423 static DECLCALLBACK(void) drvAudioCloseIn(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEIN pGstVoiceIn) 2424 { 2425 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2426 if (pGstVoiceIn) 2427 { 2428 if (!&pThis->qemuSoundCard || !pThis->qemuSoundCard.audio) 2429 { 2430 LogFlow(("DrvAudio: Error, card=%p card->audio=%p\n", 2431 (void *) &pThis->qemuSoundCard, &pThis->qemuSoundCard ? (void *) pThis->qemuSoundCard.audio : NULL)); 2432 return; 2433 } 2434 drvAudioHlpCloseIn(pThis, pThis->qemuSoundCard.audio, pGstVoiceIn); 2435 } 2436 } 2437 2438 DECLCALLBACK(void) drvAudioCloseOut(PPDMIAUDIOCONNECTOR pInterface, PPDMGSTVOICEOUT pGstVoiceOut) 2439 { 2440 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 2441 if (pGstVoiceOut) { 2442 if (!&pThis->qemuSoundCard || !pThis->qemuSoundCard.audio) 2443 { 2444 LogFlow(("DrvAudio: Error, card=%p card->audio=%p\n", 2445 (void *) &pThis->qemuSoundCard, &pThis->qemuSoundCard ? (void *) pThis->qemuSoundCard.audio : NULL)); 2446 return; 2447 } 2448 2449 drvAudioHlpCloseOut(pThis, pThis->qemuSoundCard.audio, pGstVoiceOut); 2450 } 2451 } 2452 2453 2454 /********************************************************************/ 2455 2456 1991 2457 1992 2458 /** … … 2009 2475 static DECLCALLBACK(void) drvAudioPowerOff(PPDMDRVINS pDrvIns) 2010 2476 { 2011 AudioState *s = &glob_audio_state; 2012 audio_vm_change_state_handler (s, 0); 2477 audio_vm_change_state_handler (pDrvIns, 0); 2013 2478 } 2014 2479 … … 2031 2496 audio_streamname = NULL; 2032 2497 } 2033 2034 audio_atexit (); 2035 } 2498 drvAudioExit(pDrvIns); 2499 } 2500 2036 2501 2037 2502 /** … … 2044 2509 PDRVAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIO); 2045 2510 char *drvname; 2046 int rc ;2047 2048 LogFlow(("drvAUDIOConstruct:\n")); 2511 int rc = 0; 2512 PPDMIBASE pBase; 2513 2049 2514 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 2050 2051 /*2052 * Validate the config.2053 */2054 if (!CFGMR3AreValuesValid(pCfgHandle, "AudioDriver\0StreamName\0"))2055 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;2056 2515 2057 2516 /* … … 2062 2521 pDrvIns->IBase.pfnQueryInterface = drvAudioQueryInterface; 2063 2522 /* IAudio */ 2064 /* pThis->IAudioConnector.pfn; */ 2065 2066 glob_audio_state.pDrvIns = pDrvIns; 2067 2523 pThis->IAudioConnector.pfnRead = drvAudioRead; 2524 pThis->IAudioConnector.pfnWrite = drvAudioWrite; 2525 pThis->IAudioConnector.pfnRegisterCard = drvAudioRegisterCard; 2526 pThis->IAudioConnector.pfnIsHostVoiceInOK = drvAudioIsHostVoiceInOK; 2527 pThis->IAudioConnector.pfnIsHostVoiceOutOK = drvAudioIsHostVoiceOutOK; 2528 pThis->IAudioConnector.pfnInitNull = drvAudioInitNull; 2529 pThis->IAudioConnector.pfnIsSetOutVolume = drvAudioIsSetOutVolume; 2530 pThis->IAudioConnector.pfnSetVolume = drvAudioSetVolume; 2531 pThis->IAudioConnector.pfnEnableOut = drvAudioEnableOut; 2532 pThis->IAudioConnector.pfnEnableIn = drvAudioEnableIn; 2533 pThis->IAudioConnector.pfnCloseIn = drvAudioCloseIn; 2534 pThis->IAudioConnector.pfnCloseOut = drvAudioCloseOut; 2535 pThis->IAudioConnector.pfnOpenIn = drvAudioOpenIn; 2536 pThis->IAudioConnector.pfnOpenOut = drvAudioOpenOut; 2537 pThis->IAudioConnector.pfnIsActiveIn = drvAudioIsActiveIn; 2538 pThis->IAudioConnector.pfnIsActiveOut = drvAudioIsActiveOut; 2539 /* Mixer/Conversion */ 2540 pThis->IAudioConnector.pfnConvDevFmtToStSample = drvAudioConvDevFmtToStSample; 2541 pThis->IAudioConnector.pfnConvStSampleToDevFmt = drvAudioConvStSampleToDevFmt; 2542 pThis->IAudioConnector.pfnPrepareAudioConversion = drvAudioPrepareAudioConversion; 2543 pThis->IAudioConnector.pfnEndAudioConversion = drvAudioEndAudioConversion; 2544 pThis->IAudioConnector.pfnDoRateConversion = drvAudioDoRateConversion; 2545 pThis->IAudioConnector.pfnDoRateConvAndMix = drvAudioDoRateConvAndMix; 2546 2547 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase); 2548 if (RT_FAILURE(rc)) 2549 { 2550 LogRel(("Failed to attach the audio device rc = %d \n", rc)); 2551 return rc; 2552 } 2553 pThis->pHostDrvAudio = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHOSTAUDIO); 2554 if (!pThis->pHostDrvAudio) 2555 { 2556 LogRel(("Audio: Failed to attach to underlying host driver \n")); 2557 return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW, 2558 N_("No media or async media interface below")); 2559 } 2560 2561 pThis->pDrvIns = pDrvIns; 2562 gpDrvIns = pThis->pDrvIns; 2068 2563 rc = CFGMR3QueryStringAlloc (pCfgHandle, "AudioDriver", &drvname); 2069 2564 if (RT_FAILURE (rc)) 2565 { 2566 LogFlow(("Failed to get AudioDriver from CFGM\n")); 2070 2567 return rc; 2568 } 2071 2569 2072 2570 rc = CFGMR3QueryStringAlloc (pCfgHandle, "StreamName", &audio_streamname); 2073 2571 if (RT_FAILURE (rc)) 2572 { 2573 LogFlow(("Failed to get SteamName from CFGM \n")); 2074 2574 audio_streamname = NULL; 2075 2076 rc = AUD_init (pCfgHandle, pDrvIns, drvname);2575 } 2576 rc = drvAudioInit(pCfgHandle, pDrvIns, drvname, pThis); 2077 2577 if (RT_FAILURE (rc)) 2078 2578 return rc; … … 2091 2591 static DECLCALLBACK(void) drvAudioSuspend(PPDMDRVINS pDrvIns) 2092 2592 { 2093 AudioState *s = &glob_audio_state; 2094 audio_vm_change_state_handler (s, 0); 2593 audio_vm_change_state_handler(pDrvIns, 0); 2095 2594 } 2096 2595 … … 2103 2602 static DECLCALLBACK(void) audioResume(PPDMDRVINS pDrvIns) 2104 2603 { 2105 AudioState *s = &glob_audio_state; 2106 audio_vm_change_state_handler (s, 1); 2604 audio_vm_change_state_handler(pDrvIns, 1); 2107 2605 } 2108 2606 … … 2127 2625 PDM_DRVREG_CLASS_AUDIO, 2128 2626 /* cMaxInstances */ 2129 1,2627 2, 2130 2628 /* cbInstance */ 2131 2629 sizeof(DRVAUDIO), … … 2158 2656 }; 2159 2657 2658
Note:
See TracChangeset
for help on using the changeset viewer.