- Timestamp:
- Dec 30, 2016 11:50:29 AM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 112531
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp
r63766 r65036 108 108 /** Whether we use a memory mapped file instead of our 109 109 * own allocated PCM buffer below. */ 110 bool fMemMapped; 110 /** @todo The memory mapped code seems to be utterly broken. 111 * Needs investigation! */ 112 bool fMMIO; 111 113 #endif 112 114 /** Own PCM buffer in case memory mapping is unavailable. */ … … 303 305 } 304 306 #endif 307 308 /* Check access mode (input or output). */ 309 bool fIn = ((fOpen & O_ACCMODE) == O_RDONLY); 310 311 LogRel2(("OSS: Requested %RU16 %s fragments, %RU32 bytes each\n", 312 pReq->cFragments, fIn ? "input" : "output", pReq->cbFragmentSize)); 313 305 314 int mmmmssss = (pReq->cFragments << 16) | lsbindex(pReq->cbFragmentSize); 306 315 if (ioctl(hFile, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) … … 311 320 break; 312 321 } 313 314 /* Check access mode (input or output). */315 bool fIn = ((fOpen & O_ACCMODE) == O_RDONLY);316 322 317 323 audio_buf_info abinfo; … … 331 337 pObt->cbFragmentSize = abinfo.fragsize; 332 338 339 LogRel2(("OSS: Got %RU16 %s fragments, %RU32 bytes each\n", 340 pObt->cFragments, fIn ? "input" : "output", pObt->cbFragmentSize)); 341 333 342 *phFile = hFile; 334 343 } … … 356 365 POSSAUDIOSTREAMOUT pStreamOut = (POSSAUDIOSTREAMOUT)pStream; 357 366 358 #ifdef RT_OS_L4359 return VINF_SUCCESS;360 #else361 if (!pStreamOut->fMemMapped)362 return VINF_SUCCESS;363 #endif364 365 367 int rc = VINF_SUCCESS; 366 int mask; 368 367 369 switch (enmStreamCmd) 368 370 { … … 370 372 case PDMAUDIOSTREAMCMD_RESUME: 371 373 { 372 DrvAudioHlpClearBuf(&pStreamOut->Props, 373 pStreamOut->pvBuf, pStreamOut->cbBuf, AudioMixBufSize(&pStream->MixBuf));374 375 mask = PCM_ENABLE_OUTPUT;374 DrvAudioHlpClearBuf(&pStreamOut->Props, pStreamOut->pvBuf, pStreamOut->cbBuf, 375 AUDIOMIXBUF_B2S(&pStream->MixBuf, pStreamOut->cbBuf)); 376 377 int mask = PCM_ENABLE_OUTPUT; 376 378 if (ioctl(pStreamOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0) 377 379 { … … 386 388 case PDMAUDIOSTREAMCMD_PAUSE: 387 389 { 388 mask = 0;390 int mask = 0; 389 391 if (ioctl(pStreamOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0) 390 392 { … … 423 425 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 424 426 */ 425 static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 427 static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 428 PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 426 429 { 427 430 RT_NOREF(pInterface, cbBuf, pvBuf); … … 542 545 543 546 #ifndef RT_OS_L4 544 if (pStrm->fM emMapped)547 if (pStrm->fMMIO) 545 548 { 546 549 if (pStrm->pvBuf) … … 554 557 pStrm->cbBuf = 0; 555 558 556 pStrm->fM emMapped= false;559 pStrm->fMMIO = false; 557 560 } 558 561 else … … 671 674 pCfgAcq->enmFormat = obtStream.enmFormat; 672 675 pCfgAcq->uHz = obtStream.uFreq; 673 pCfgAcq->cChannels = pCfgReq->cChannels; /** @todo r=andy Why not using obtStream? */676 pCfgAcq->cChannels = obtStream.cChannels; 674 677 pCfgAcq->enmEndianness = obtStream.enmENDIANNESS; 675 678 … … 738 741 reqStream.cbFragmentSize = s_OSSConf.fragsize; 739 742 740 rc = ossStreamOpen(s_OSSConf.devpath_out, O_WRONLY | O_NONBLOCK, &reqStream, &obtStream, &hFile);743 rc = ossStreamOpen(s_OSSConf.devpath_out, O_WRONLY, &reqStream, &obtStream, &hFile); 741 744 if (RT_SUCCESS(rc)) 742 745 { 743 746 pCfgAcq->enmFormat = obtStream.enmFormat; 744 747 pCfgAcq->uHz = obtStream.uFreq; 745 pCfgAcq->cChannels = pCfgReq->cChannels; /** @todo r=andy Why not using obtStream? */748 pCfgAcq->cChannels = obtStream.cChannels; 746 749 pCfgAcq->enmEndianness = obtStream.enmENDIANNESS; 747 750 … … 761 764 if (RT_SUCCESS(rc)) 762 765 { 763 pStrm->fMemMapped = false; 764 765 size_t cbSamples = cSamples << pStrm->Props.cShift; 766 pStrm->fMMIO = false; 767 768 size_t cbSample = (1 << pStrm->Props.cShift); 769 770 size_t cbSamples = cSamples * cbSample; 766 771 Assert(cbSamples); 767 772 … … 795 800 } 796 801 else 797 pStrm->fMemMapped = true; 802 { 803 pStrm->fMMIO = true; 804 LogRel(("OSS: Using MMIO\n")); 805 } 798 806 } 799 807 … … 811 819 /* Memory mapping failed above? Try allocating an own buffer. */ 812 820 #ifndef RT_OS_L4 813 if (!pStrm->fM emMapped)821 if (!pStrm->fMMIO) 814 822 { 815 823 #endif … … 844 852 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 845 853 */ 846 static DECLCALLBACK(int) drvHostOSSAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 854 static DECLCALLBACK(int) drvHostOSSAudioStreamPlay(PPDMIHOSTAUDIO pInterface, 855 PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 856 uint32_t *pcbWritten) 847 857 { 848 858 RT_NOREF(pInterface, cbBuf, pvBuf); … … 852 862 853 863 int rc = VINF_SUCCESS; 854 uint32_t cbReadTotal = 0; 864 uint32_t cbWrittenTotal = 0; 865 866 #ifndef RT_OS_L4 855 867 count_info cntinfo; 868 #endif 856 869 857 870 do … … 859 872 size_t cbBufSize = AudioMixBufSizeBytes(&pStream->MixBuf); 860 873 861 uint32_t c Live = AudioMixBufLive(&pStream->MixBuf);862 uint32_t c ToRead;874 uint32_t csLive = AudioMixBufLive(&pStream->MixBuf); 875 uint32_t csToRead; 863 876 864 877 #ifndef RT_OS_L4 865 if (pStrm->fM emMapped)878 if (pStrm->fMMIO) 866 879 { 867 880 /* Get current playback pointer. */ … … 869 882 if (!rc2) 870 883 { 871 LogRel(("OSS: Failed to retrieve current playback pointer: %s\n", 872 strerror(errno))); 884 LogRel(("OSS: Failed to retrieve current playback pointer: %s\n", strerror(errno))); 873 885 rc = RTErrConvertFromErrno(errno); 874 886 break; … … 886 898 Assert(cbData); 887 899 888 c ToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, cbData),889 c Live);900 csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, cbData), 901 csLive); 890 902 } 891 903 else … … 903 915 if ((size_t)abinfo.bytes > cbBufSize) 904 916 { 905 Log FlowFunc(("Warning: Invalid available size, size=%d, bufsize=%zu\n", abinfo.bytes, cbBufSize));917 LogRel2(("OSS: Warning: Too big output size (%d > %zu), limiting to %zu\n", abinfo.bytes, cbBufSize, cbBufSize)); 906 918 abinfo.bytes = cbBufSize; 907 919 /* Keep going. */ … … 910 922 if (abinfo.bytes < 0) 911 923 { 912 Log FlowFunc(("Warning: Invalid available size, size=%d, bufsize=%zu\n", abinfo.bytes, cbBufSize));924 LogRel2(("OSS: Warning: Invalid available size (%d vs. %zu)\n", abinfo.bytes, cbBufSize)); 913 925 rc = VERR_INVALID_PARAMETER; 914 926 break; 915 927 } 916 928 917 c ToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, abinfo.bytes), cLive);918 if (!c ToRead)929 csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, abinfo.fragments * abinfo.fragsize), csLive); 930 if (!csToRead) 919 931 break; 920 932 #ifndef RT_OS_L4 921 933 } 922 934 #endif 923 size_t cbToRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cToRead); 924 LogFlowFunc(("cbToRead=%zu\n", cbToRead)); 925 926 uint32_t cRead, cbRead; 935 size_t cbToRead = RT_MIN(AUDIOMIXBUF_S2B(&pStream->MixBuf, csToRead), pStrm->cbBuf); 936 937 uint32_t csRead, cbRead; 927 938 while (cbToRead) 928 939 { 929 rc = AudioMixBufReadCirc(&pStream->MixBuf, pStrm->pvBuf, cbToRead, &c Read);940 rc = AudioMixBufReadCirc(&pStream->MixBuf, pStrm->pvBuf, cbToRead, &csRead); 930 941 if (RT_FAILURE(rc)) 931 942 break; 932 943 933 cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead); 934 ssize_t cbWritten = write(pStrm->hFile, pStrm->pvBuf, cbRead); 935 if (cbWritten == -1) 936 { 937 LogRel(("OSS: Failed writing output data: %s\n", strerror(errno))); 938 rc = RTErrConvertFromErrno(errno); 939 break; 944 cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, csRead); 945 946 uint32_t cbChunk = cbRead; 947 uint32_t cbChunkOff = 0; 948 while (cbChunk) 949 { 950 ssize_t cbChunkWritten = write(pStrm->hFile, (uint8_t *)pStrm->pvBuf + cbChunkOff, RT_MIN(cbChunk, 4096)); 951 if (cbChunkWritten < 0) 952 { 953 LogRel(("OSS: Failed writing output data: %s\n", strerror(errno))); 954 rc = RTErrConvertFromErrno(errno); 955 break; 956 } 957 958 if (cbChunkWritten & pStrm->Props.uAlign) 959 { 960 LogRel(("OSS: Misaligned write (written %z, expected %RU32)\n", cbChunkWritten, cbChunk)); 961 break; 962 } 963 964 cbChunkOff += cbChunkWritten; 965 Assert(cbChunkOff <= cbRead); 966 Assert(cbChunk >= cbChunkWritten); 967 cbChunk -= cbChunkWritten; 940 968 } 941 969 942 970 Assert(cbToRead >= cbRead); 943 cbToRead -= cbRead;944 cb ReadTotal += cbRead;971 cbToRead -= cbRead; 972 cbWrittenTotal += cbRead; 945 973 } 946 974 947 975 #ifndef RT_OS_L4 948 976 /* Update read pointer. */ 949 if (pStrm->fM emMapped)977 if (pStrm->fMMIO) 950 978 pStrm->old_optr = cntinfo.ptr; 951 979 #endif … … 955 983 if (RT_SUCCESS(rc)) 956 984 { 957 uint32_t c ReadTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbReadTotal);958 if (c ReadTotal)959 AudioMixBufFinish(&pStream->MixBuf, c ReadTotal);985 uint32_t cWrittenTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbWrittenTotal); 986 if (cWrittenTotal) 987 AudioMixBufFinish(&pStream->MixBuf, cWrittenTotal); 960 988 961 989 if (pcbWritten) 962 *pcbWritten = cReadTotal; 963 964 LogFlowFunc(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n", cReadTotal, cbReadTotal, rc)); 990 *pcbWritten = cbWrittenTotal; 965 991 } 966 992 … … 994 1020 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 995 1021 */ 996 static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1022 static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 1023 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 997 1024 { 998 1025 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 1032 1059 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 1033 1060 */ 1034 static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1061 static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 1062 PDMAUDIOSTREAMCMD enmStreamCmd) 1035 1063 { 1036 1064 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
Note:
See TracChangeset
for help on using the changeset viewer.