Changeset 89768 in vbox for trunk/include
- Timestamp:
- Jun 17, 2021 11:03:19 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145220
- Location:
- trunk/include/VBox/vmm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmaudioifs.h
r89510 r89768 691 691 692 692 /** 693 * Audio stream commands. 694 * 695 * Used in the audio connector as well as in the actual host backends. 696 */ 697 typedef enum PDMAUDIOSTREAMCMD 698 { 699 /** Invalid zero value as per usual (guards against using unintialized values). */ 700 PDMAUDIOSTREAMCMD_INVALID = 0, 701 /** Enables the stream. */ 702 PDMAUDIOSTREAMCMD_ENABLE, 703 /** Pauses the stream. 704 * This is currently only issued when the VM is suspended (paused). 705 * @remarks This is issued by DrvAudio, never by the mixer or devices. */ 706 PDMAUDIOSTREAMCMD_PAUSE, 707 /** Resumes the stream. 708 * This is currently only issued when the VM is resumed. 709 * @remarks This is issued by DrvAudio, never by the mixer or devices. */ 710 PDMAUDIOSTREAMCMD_RESUME, 711 /** Drain the stream, that is, play what's in the buffers and then stop. 712 * 713 * There will be no more samples written after this command is issued. 714 * PDMIAUDIOCONNECTOR::pfnStreamIterate will drive progress for DrvAudio and 715 * calls to PDMIHOSTAUDIO::pfnStreamPlay with a zero sized buffer will provide 716 * the backend with a way to drive it forwards. These calls will come at a 717 * frequency set by the device and be on an asynchronous I/O thread. 718 * 719 * A DISABLE command maybe submitted if the device/mixer wants to re-enable the 720 * stream while it's still draining or if it gets impatient and thinks the 721 * draining has been going on too long, in which case the stream should stop 722 * immediately. 723 * 724 * @note This should not wait for the stream to finish draining, just change 725 * the state. (The caller could be an EMT and it must not block for 726 * hundreds of milliseconds of buffer to finish draining.) 727 * 728 * @note Does not apply to input streams. Backends should refuse such requests. */ 729 PDMAUDIOSTREAMCMD_DRAIN, 730 /** Stops the stream immediately w/o any draining. */ 731 PDMAUDIOSTREAMCMD_DISABLE, 732 /** End of valid values. */ 733 PDMAUDIOSTREAMCMD_END, 734 /** Hack to blow the type up to 32-bit. */ 735 PDMAUDIOSTREAMCMD_32BIT_HACK = 0x7fffffff 736 } PDMAUDIOSTREAMCMD; 737 738 /** 739 * Backend status. 740 */ 741 typedef enum PDMAUDIOBACKENDSTS 742 { 743 /** Unknown/invalid status. */ 744 PDMAUDIOBACKENDSTS_UNKNOWN = 0, 745 /** No backend attached. */ 746 PDMAUDIOBACKENDSTS_NOT_ATTACHED, 747 /** The backend is in its initialization phase. 748 * Not all backends support this status. */ 749 PDMAUDIOBACKENDSTS_INITIALIZING, 750 /** The backend has stopped its operation. */ 751 PDMAUDIOBACKENDSTS_STOPPED, 752 /** The backend is up and running. */ 753 PDMAUDIOBACKENDSTS_RUNNING, 754 /** The backend ran into an error and is unable to recover. 755 * A manual re-initialization might help. */ 756 PDMAUDIOBACKENDSTS_ERROR, 757 /** Hack to blow the type up to 32-bit. */ 758 PDMAUDIOBACKENDSTS_32BIT_HACK = 0x7fffffff 759 } PDMAUDIOBACKENDSTS; 760 761 /** 762 * PDM audio stream state. 763 * 764 * This is all the mixer/device needs. The PDMAUDIOSTREAM_STS_XXX stuff will 765 * become DrvAudio internal state once the backend stuff is destilled out of it. 766 * 767 * @note The value order is significant, don't change it willy-nilly. 768 */ 769 typedef enum PDMAUDIOSTREAMSTATE 770 { 771 /** Invalid state value. */ 772 PDMAUDIOSTREAMSTATE_INVALID = 0, 773 /** The stream is not operative and cannot be enabled. */ 774 PDMAUDIOSTREAMSTATE_NOT_WORKING, 775 /** The stream needs to be re-initialized by the device/mixer 776 * (i.e. call PDMIAUDIOCONNECTOR::pfnStreamReInit). */ 777 PDMAUDIOSTREAMSTATE_NEED_REINIT, 778 /** The stream is inactive (not enabled). */ 779 PDMAUDIOSTREAMSTATE_INACTIVE, 780 /** The stream is enabled but nothing to read/write. 781 * @todo not sure if we need this variant... */ 782 PDMAUDIOSTREAMSTATE_ENABLED, 783 /** The stream is enabled and captured samples can be read. */ 784 PDMAUDIOSTREAMSTATE_ENABLED_READABLE, 785 /** The stream is enabled and samples can be written for playback. */ 786 PDMAUDIOSTREAMSTATE_ENABLED_WRITABLE, 787 /** End of valid states. */ 788 PDMAUDIOSTREAMSTATE_END, 789 /** Make sure the type is 32-bit wide. */ 790 PDMAUDIOSTREAMSTATE_32BIT_HACK = 0x7fffffff 791 } PDMAUDIOSTREAMSTATE; 792 793 /** @name PDMAUDIOSTREAM_CREATE_F_XXX 794 * @{ */ 795 /** Does not need any mixing buffers, the device takes care of all conversion. 796 * @note this is now default and assumed always set. */ 797 #define PDMAUDIOSTREAM_CREATE_F_NO_MIXBUF RT_BIT_32(0) 798 /** @} */ 799 800 /** @name PDMAUDIOSTREAM_WARN_FLAGS_XXX 801 * @{ */ 802 /** No stream warning flags set. */ 803 #define PDMAUDIOSTREAM_WARN_FLAGS_NONE 0 804 /** Warned about a disabled stream. */ 805 #define PDMAUDIOSTREAM_WARN_FLAGS_DISABLED RT_BIT(0) 806 /** @} */ 807 808 /** 809 * An input or output audio stream. 810 */ 811 typedef struct PDMAUDIOSTREAM 812 { 813 /** Critical section protecting the stream. 814 * 815 * When not otherwise stated, DrvAudio will enter this before calling the 816 * backend. The backend and device/mixer can normally safely enter it prior to 817 * a DrvAudio call, however not to pfnStreamDestroy, pfnStreamRelease or 818 * anything that may access the stream list. 819 * 820 * @note Lock ordering: 821 * - After DRVAUDIO::CritSectGlobals. 822 * - Before DRVAUDIO::CritSectHotPlug. */ 823 RTCRITSECT CritSect; 824 /** Stream configuration. */ 825 PDMAUDIOSTREAMCFG Cfg; 826 /** Magic value (PDMAUDIOSTREAM_MAGIC). */ 827 uint32_t uMagic; 828 /** Size (in bytes) of the backend-specific stream data. */ 829 uint32_t cbBackend; 830 /** Warnings shown already in the release log. 831 * See PDMAUDIOSTREAM_WARN_FLAGS_XXX. */ 832 uint32_t fWarningsShown; 833 } PDMAUDIOSTREAM; 834 /** Pointer to an audio stream. */ 835 typedef struct PDMAUDIOSTREAM *PPDMAUDIOSTREAM; 836 /** Pointer to a const audio stream. */ 837 typedef struct PDMAUDIOSTREAM const *PCPDMAUDIOSTREAM; 838 839 /** Magic value for PDMAUDIOSTREAM. */ 840 #define PDMAUDIOSTREAM_MAGIC PDM_VERSION_MAKE(0xa0d3, 5, 0) 841 842 843 844 /** Pointer to a audio connector interface. */ 845 typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR; 846 847 /** 848 * Audio connector interface (up). 849 */ 850 typedef struct PDMIAUDIOCONNECTOR 851 { 852 /** 853 * Enables or disables the given audio direction for this driver. 854 * 855 * When disabled, assiociated output streams consume written audio without passing them further down to the backends. 856 * Associated input streams then return silence when read from those. 857 * 858 * @returns VBox status code. 859 * @param pInterface Pointer to the interface structure containing the called function pointer. 860 * @param enmDir Audio direction to enable or disable driver for. 861 * @param fEnable Whether to enable or disable the specified audio direction. 862 * 863 * @note Be very careful when using this function, as this could 864 * violate / run against the (global) VM settings. See @bugref{9882}. 865 */ 866 DECLR3CALLBACKMEMBER(int, pfnEnable, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir, bool fEnable)); 867 868 /** 869 * Returns whether the given audio direction for this driver is enabled or not. 870 * 871 * @returns True if audio is enabled for the given direction, false if not. 872 * @param pInterface Pointer to the interface structure containing the called function pointer. 873 * @param enmDir Audio direction to retrieve enabled status for. 874 */ 875 DECLR3CALLBACKMEMBER(bool, pfnIsEnabled, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir)); 876 877 /** 878 * Retrieves the current configuration of the host audio backend. 879 * 880 * @returns VBox status code. 881 * @param pInterface Pointer to the interface structure containing the called function pointer. 882 * @param pCfg Where to store the host audio backend configuration data. 883 */ 884 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOBACKENDCFG pCfg)); 885 886 /** 887 * Retrieves the current status of the host audio backend. 888 * 889 * @returns Status of the host audio backend. 890 * @param pInterface Pointer to the interface structure containing the called function pointer. 891 * @param enmDir Audio direction to check host audio backend for. Specify PDMAUDIODIR_DUPLEX for the overall 892 * backend status. 893 */ 894 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir)); 895 896 /** 897 * Gives the audio drivers a hint about a typical configuration. 898 * 899 * This is a little hack for windows (and maybe other hosts) where stream 900 * creation can take a relatively long time, making it very unsuitable for EMT. 901 * The audio backend can use this hint to cache pre-configured stream setups, 902 * so that when the guest actually wants to play something EMT won't be blocked 903 * configuring host audio. 904 * 905 * @param pInterface Pointer to this interface. 906 * @param pCfg The typical configuration. Can be modified by the 907 * drivers in unspecified ways. 908 */ 909 DECLR3CALLBACKMEMBER(void, pfnStreamConfigHint, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg)); 910 911 /** 912 * Creates an audio stream. 913 * 914 * @returns VBox status code. 915 * @param pInterface Pointer to this interface. 916 * @param fFlags PDMAUDIOSTREAM_CREATE_F_XXX. 917 * @param pCfgReq The requested stream configuration. The actual stream 918 * configuration can be found in pStream->Cfg on success. 919 * @param ppStream Pointer where to return the created audio stream on 920 * success. 921 */ 922 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, uint32_t fFlags, PCPDMAUDIOSTREAMCFG pCfgReq, 923 PPDMAUDIOSTREAM *ppStream)); 924 925 926 /** 927 * Destroys an audio stream. 928 * 929 * @param pInterface Pointer to the interface structure containing the called function pointer. 930 * @param pStream Pointer to audio stream. 931 * @param fImmediate Whether to immdiately stop and destroy a draining 932 * stream (@c true), or to allow it to complete 933 * draining first (@c false) if that's feasable. 934 * The latter depends on the draining stage and what 935 * the backend is capable of. 936 */ 937 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, bool fImmediate)); 938 939 /** 940 * Re-initializes the stream in response to PDMAUDIOSTREAM_STS_NEED_REINIT. 941 * 942 * @returns VBox status code. 943 * @param pInterface Pointer to this interface. 944 * @param pStream The audio stream needing re-initialization. 945 */ 946 DECLR3CALLBACKMEMBER(int, pfnStreamReInit, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 947 948 /** 949 * Adds a reference to the specified audio stream. 950 * 951 * @returns New reference count. UINT32_MAX on error. 952 * @param pInterface Pointer to the interface structure containing the called function pointer. 953 * @param pStream Pointer to audio stream adding the reference to. 954 */ 955 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRetain, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 956 957 /** 958 * Releases a reference from the specified stream. 959 * 960 * @returns New reference count. UINT32_MAX on error. 961 * @param pInterface Pointer to the interface structure containing the called function pointer. 962 * @param pStream Pointer to audio stream releasing a reference from. 963 */ 964 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRelease, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 965 966 /** 967 * Controls a specific audio stream. 968 * 969 * @returns VBox status code. 970 * @param pInterface Pointer to the interface structure containing the called function pointer. 971 * @param pStream Pointer to audio stream. 972 * @param enmStreamCmd The stream command to issue. 973 */ 974 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, 975 PDMAUDIOSTREAMCMD enmStreamCmd)); 976 977 /** 978 * Processes stream data. 979 * 980 * @param pInterface Pointer to the interface structure containing the called function pointer. 981 * @param pStream Pointer to audio stream. 982 */ 983 DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 984 985 /** 986 * Returns the state of a specific audio stream (destilled status). 987 * 988 * @returns PDMAUDIOSTREAMSTATE value. 989 * @retval PDMAUDIOSTREAMSTATE_INVALID if the input isn't valid (w/ assertion). 990 * @param pInterface Pointer to the interface structure containing the called function pointer. 991 * @param pStream Pointer to audio stream. 992 */ 993 DECLR3CALLBACKMEMBER(PDMAUDIOSTREAMSTATE, pfnStreamGetState, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 994 995 /** 996 * Returns the number of bytes that can be written to an audio output stream. 997 * 998 * @returns Number of bytes writable data. 999 * @param pInterface Pointer to the interface structure containing the called function pointer. 1000 * @param pStream Pointer to audio stream. 1001 */ 1002 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 1003 1004 /** 1005 * Plays (writes to) an audio output stream. 1006 * 1007 * @returns VBox status code. 1008 * @param pInterface Pointer to the interface structure containing the called function pointer. 1009 * @param pStream Pointer to audio stream to read from. 1010 * @param pvBuf Audio data to be written. 1011 * @param cbBuf Number of bytes to be written. 1012 * @param pcbWritten Bytes of audio data written. Optional. 1013 */ 1014 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, 1015 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)); 1016 1017 /** 1018 * Returns the number of bytes that can be read from an input stream. 1019 * 1020 * @returns Number of bytes of readable data. 1021 * @param pInterface Pointer to the interface structure containing the called function pointer. 1022 * @param pStream Pointer to audio stream. 1023 */ 1024 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 1025 1026 /** 1027 * Captures (reads) samples from an audio input stream. 1028 * 1029 * @returns VBox status code. 1030 * @param pInterface Pointer to the interface structure containing the called function pointer. 1031 * @param pStream Pointer to audio stream to write to. 1032 * @param pvBuf Where to store the read data. 1033 * @param cbBuf Number of bytes to read. 1034 * @param pcbRead Bytes of audio data read. Optional. 1035 */ 1036 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, 1037 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)); 1038 } PDMIAUDIOCONNECTOR; 1039 1040 /** PDMIAUDIOCONNECTOR interface ID. */ 1041 #define PDMIAUDIOCONNECTOR_IID "2900fe2a-6aeb-4953-ac12-f8965612f446" 1042 1043 1044 /** 1045 * Host audio backend specific stream data. 1046 * 1047 * The backend will put this as the first member of it's own data structure. 1048 */ 1049 typedef struct PDMAUDIOBACKENDSTREAM 1050 { 1051 /** Magic value (PDMAUDIOBACKENDSTREAM_MAGIC). */ 1052 uint32_t uMagic; 1053 /** Explicit zero padding - do not touch! */ 1054 uint32_t uReserved; 1055 /** Pointer to the stream this backend data is associated with. */ 1056 PPDMAUDIOSTREAM pStream; 1057 /** Reserved for future use (zeroed) - do not touch. */ 1058 void *apvReserved[2]; 1059 } PDMAUDIOBACKENDSTREAM; 1060 /** Pointer to host audio specific stream data! */ 1061 typedef PDMAUDIOBACKENDSTREAM *PPDMAUDIOBACKENDSTREAM; 1062 1063 /** Magic value for PDMAUDIOBACKENDSTREAM. */ 1064 #define PDMAUDIOBACKENDSTREAM_MAGIC PDM_VERSION_MAKE(0xa0d4, 1, 0) 1065 1066 /** 1067 * Host audio (backend) stream state returned by PDMIHOSTAUDIO::pfnStreamGetState. 1068 */ 1069 typedef enum PDMHOSTAUDIOSTREAMSTATE 1070 { 1071 /** Invalid zero value, as per usual. */ 1072 PDMHOSTAUDIOSTREAMSTATE_INVALID = 0, 1073 /** The stream is being initialized. 1074 * This should also be used when switching to a new device and the stream 1075 * stops to work with the old device while the new one being configured. */ 1076 PDMHOSTAUDIOSTREAMSTATE_INITIALIZING, 1077 /** The stream does not work (async init failed, audio subsystem gone 1078 * fishing, or similar). */ 1079 PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING, 1080 /** Backend is working okay. */ 1081 PDMHOSTAUDIOSTREAMSTATE_OKAY, 1082 /** Backend is working okay, but currently draining the stream. */ 1083 PDMHOSTAUDIOSTREAMSTATE_DRAINING, 1084 /** Backend is working but doesn't want any commands or data reads/writes. */ 1085 PDMHOSTAUDIOSTREAMSTATE_INACTIVE, 1086 /** End of valid values. */ 1087 PDMHOSTAUDIOSTREAMSTATE_END, 1088 /** Blow the type up to 32 bits. */ 1089 PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK = 0x7fffffff 1090 } PDMHOSTAUDIOSTREAMSTATE; 1091 1092 1093 /** Pointer to a host audio interface. */ 1094 typedef struct PDMIHOSTAUDIO *PPDMIHOSTAUDIO; 1095 1096 /** 1097 * PDM host audio interface. 1098 */ 1099 typedef struct PDMIHOSTAUDIO 1100 { 1101 /** 1102 * Returns the host backend's configuration (backend). 1103 * 1104 * @returns VBox status code. 1105 * @param pInterface Pointer to the interface structure containing the called function pointer. 1106 * @param pBackendCfg Where to store the backend audio configuration to. 1107 */ 1108 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)); 1109 1110 /** 1111 * Returns (enumerates) host audio device information (optional). 1112 * 1113 * @returns VBox status code. 1114 * @param pInterface Pointer to the interface structure containing the called function pointer. 1115 * @param pDeviceEnum Where to return the enumerated audio devices. 1116 */ 1117 DECLR3CALLBACKMEMBER(int, pfnGetDevices, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum)); 1118 1119 /** 1120 * Changes the output or input device. 1121 * 1122 * @returns VBox status code. 1123 * @param pInterface Pointer to this interface. 1124 * @param enmDir The direction to set the device for: PDMAUDIODIR_IN, 1125 * PDMAUDIODIR_OUT or PDMAUDIODIR_DUPLEX (both the 1126 * previous). 1127 * @param pszId The PDMAUDIOHOSTDEV::pszId value of the device to 1128 * use, or NULL / empty string for the default device. 1129 */ 1130 DECLR3CALLBACKMEMBER(int, pfnSetDevice, (PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir, const char *pszId)); 1131 1132 /** 1133 * Returns the current status from the audio backend (optional). 1134 * 1135 * @returns PDMAUDIOBACKENDSTS enum. 1136 * @param pInterface Pointer to the interface structure containing the called function pointer. 1137 * @param enmDir Audio direction to get status for. Pass PDMAUDIODIR_DUPLEX for overall status. 1138 */ 1139 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)); 1140 1141 /** 1142 * Callback for genric on-worker-thread requests initiated by the backend itself. 1143 * 1144 * This is the counterpart to PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread that will 1145 * be invoked on a worker thread when the backend requests it - optional. 1146 * 1147 * This does not return a value, so the backend must keep track of 1148 * failure/success on its own. 1149 * 1150 * This method is optional. A non-NULL will, together with pfnStreamInitAsync 1151 * and PDMAUDIOBACKEND_F_ASYNC_HINT, force DrvAudio to create the thread pool. 1152 * 1153 * @param pInterface Pointer to this interface. 1154 * @param pStream Optionally a backend stream if specified in the 1155 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call. 1156 * @param uUser User specific value as specified in the 1157 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call. 1158 * @param pvUser User specific pointer as specified in the 1159 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call. 1160 */ 1161 DECLR3CALLBACKMEMBER(void, pfnDoOnWorkerThread,(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1162 uintptr_t uUser, void *pvUser)); 1163 1164 /** 1165 * Gives the audio backend a hint about a typical configuration (optional). 1166 * 1167 * This is a little hack for windows (and maybe other hosts) where stream 1168 * creation can take a relatively long time, making it very unsuitable for EMT. 1169 * The audio backend can use this hint to cache pre-configured stream setups, 1170 * so that when the guest actually wants to play something EMT won't be blocked 1171 * configuring host audio. 1172 * 1173 * The backend can return PDMAUDIOBACKEND_F_ASYNC_HINT in 1174 * PDMIHOSTAUDIO::pfnGetConfig to avoid having EMT making this call and thereby 1175 * speeding up VM construction. 1176 * 1177 * @param pInterface Pointer to this interface. 1178 * @param pCfg The typical configuration. (Feel free to change it 1179 * to the actual stream config that would be used, 1180 * however caller will probably ignore this.) 1181 */ 1182 DECLR3CALLBACKMEMBER(void, pfnStreamConfigHint, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAMCFG pCfg)); 1183 1184 /** 1185 * Creates an audio stream using the requested stream configuration. 1186 * 1187 * If a backend is not able to create this configuration, it will return its 1188 * best match in the acquired configuration structure on success. 1189 * 1190 * @returns VBox status code. 1191 * @retval VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED if 1192 * PDMIHOSTAUDIO::pfnStreamInitAsync should be called. 1193 * @param pInterface Pointer to this interface. 1194 * @param pStream Pointer to the audio stream. 1195 * @param pCfgReq The requested stream configuration. 1196 * @param pCfgAcq The acquired stream configuration - output. This is 1197 * the same as @a *pCfgReq when called, the 1198 * implementation will adjust it to make the actual 1199 * stream configuration as needed. 1200 */ 1201 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1202 PCPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)); 1203 1204 /** 1205 * Asynchronous stream initialization step, optional. 1206 * 1207 * This is called on a worker thread iff the PDMIHOSTAUDIO::pfnStreamCreate 1208 * method returns VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED. 1209 * 1210 * @returns VBox status code. 1211 * @param pInterface Pointer to this interface. 1212 * @param pStream Pointer to audio stream to continue 1213 * initialization of. 1214 * @param fDestroyed Set to @c true if the stream has been destroyed 1215 * before the worker thread got to making this 1216 * call. The backend should just ready the stream 1217 * for destruction in that case. 1218 */ 1219 DECLR3CALLBACKMEMBER(int, pfnStreamInitAsync, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fDestroyed)); 1220 1221 /** 1222 * Destroys an audio stream. 1223 * 1224 * @returns VBox status code. 1225 * @param pInterface Pointer to the interface containing the called function. 1226 * @param pStream Pointer to audio stream. 1227 * @param fImmediate Whether to immdiately stop and destroy a draining 1228 * stream (@c true), or to allow it to complete 1229 * draining first (@c false) if that's feasable. 1230 */ 1231 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fImmediate)); 1232 1233 /** 1234 * Called from PDMIHOSTAUDIOPORT::pfnNotifyDeviceChanged so the backend can start 1235 * the device change for a stream. 1236 * 1237 * This is mainly to avoid the need for a list of streams in the backend. 1238 * 1239 * @param pInterface Pointer to this interface. 1240 * @param pStream Pointer to audio stream (locked). 1241 * @param pvUser Backend specific parameter from the call to 1242 * PDMIHOSTAUDIOPORT::pfnNotifyDeviceChanged. 1243 */ 1244 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyDeviceChanged,(PPDMIHOSTAUDIO pInterface, 1245 PPDMAUDIOBACKENDSTREAM pStream, void *pvUser)); 1246 1247 /** 1248 * Enables (starts) the stream. 1249 * 1250 * @returns VBox status code. 1251 * @param pInterface Pointer to this interface. 1252 * @param pStream Pointer to the audio stream to enable. 1253 * @sa PDMAUDIOSTREAMCMD_ENABLE 1254 */ 1255 DECLR3CALLBACKMEMBER(int, pfnStreamEnable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1256 1257 /** 1258 * Disables (stops) the stream immediately. 1259 * 1260 * @returns VBox status code. 1261 * @param pInterface Pointer to this interface. 1262 * @param pStream Pointer to the audio stream to disable. 1263 * @sa PDMAUDIOSTREAMCMD_DISABLE 1264 */ 1265 DECLR3CALLBACKMEMBER(int, pfnStreamDisable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1266 1267 /** 1268 * Pauses the stream - called when the VM is suspended. 1269 * 1270 * @returns VBox status code. 1271 * @param pInterface Pointer to this interface. 1272 * @param pStream Pointer to the audio stream to pause. 1273 * @sa PDMAUDIOSTREAMCMD_PAUSE 1274 */ 1275 DECLR3CALLBACKMEMBER(int, pfnStreamPause, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1276 1277 /** 1278 * Resumes a paused stream - called when the VM is resumed. 1279 * 1280 * @returns VBox status code. 1281 * @param pInterface Pointer to this interface. 1282 * @param pStream Pointer to the audio stream to resume. 1283 * @sa PDMAUDIOSTREAMCMD_RESUME 1284 */ 1285 DECLR3CALLBACKMEMBER(int, pfnStreamResume, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1286 1287 /** 1288 * Drain the stream, that is, play what's in the buffers and then stop. 1289 * 1290 * There will be no more samples written after this command is issued. 1291 * PDMIHOSTAUDIO::pfnStreamPlay with a zero sized buffer will provide the 1292 * backend with a way to drive it forwards. These calls will come at a 1293 * frequency set by the device and be on an asynchronous I/O thread. 1294 * 1295 * The PDMIHOSTAUDIO::pfnStreamDisable method maybe called if the device/mixer 1296 * wants to re-enable the stream while it's still draining or if it gets 1297 * impatient and thinks the draining has been going on too long, in which case 1298 * the stream should stop immediately. 1299 * 1300 * @note This should not wait for the stream to finish draining, just change 1301 * the state. (The caller could be an EMT and it must not block for 1302 * hundreds of milliseconds of buffer to finish draining.) 1303 * 1304 * @note Does not apply to input streams. Backends should refuse such 1305 * requests. 1306 * 1307 * @returns VBox status code. 1308 * @retval VERR_WRONG_ORDER if not output stream. 1309 * @param pInterface Pointer to this interface. 1310 * @param pStream Pointer to the audio stream to drain. 1311 * @sa PDMAUDIOSTREAMCMD_DRAIN 1312 */ 1313 DECLR3CALLBACKMEMBER(int, pfnStreamDrain, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1314 1315 /** 1316 * Returns the current state of the given backend stream. 1317 * 1318 * @returns PDMHOSTAUDIOSTREAMSTATE value. 1319 * @retval PDMHOSTAUDIOSTREAMSTATE_INVALID if invalid stream. 1320 * @param pInterface Pointer to the interface structure containing the called function pointer. 1321 * @param pStream Pointer to audio stream. 1322 */ 1323 DECLR3CALLBACKMEMBER(PDMHOSTAUDIOSTREAMSTATE, pfnStreamGetState, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1324 1325 /** 1326 * Returns the number of buffered bytes that hasn't been played yet (optional). 1327 * 1328 * Is not valid on an input stream, implementions shall assert and return zero. 1329 * 1330 * @returns Number of pending bytes. 1331 * @param pInterface Pointer to this interface. 1332 * @param pStream Pointer to the audio stream. 1333 * 1334 * @todo This is no longer not used by DrvAudio and can probably be removed. 1335 */ 1336 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetPending, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1337 1338 /** 1339 * Returns the amount which is writable to the audio (output) stream. 1340 * 1341 * @returns Number of writable bytes. 1342 * @param pInterface Pointer to the interface structure containing the called function pointer. 1343 * @param pStream Pointer to audio stream. 1344 */ 1345 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1346 1347 /** 1348 * Plays (writes to) an audio (output) stream. 1349 * 1350 * This is always called with data in the buffer, except after 1351 * PDMAUDIOSTREAMCMD_DRAIN is issued when it's called every so often to assist 1352 * the backend with moving the draining operation forward (kind of like 1353 * PDMIAUDIOCONNECTOR::pfnStreamIterate). 1354 * 1355 * @returns VBox status code. 1356 * @param pInterface Pointer to the interface structure containing the called function pointer. 1357 * @param pStream Pointer to audio stream. 1358 * @param pvBuf Pointer to audio data buffer to play. This will be NULL 1359 * when called to assist draining the stream. 1360 * @param cbBuf The number of bytes of audio data to play. This will be 1361 * zero when called to assist draining the stream. 1362 * @param pcbWritten Where to return the actual number of bytes played. 1363 */ 1364 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1365 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)); 1366 1367 /** 1368 * Returns the amount which is readable from the audio (input) stream. 1369 * 1370 * @returns For non-raw layout streams: Number of readable bytes. 1371 * for raw layout streams : Number of readable audio frames. 1372 * @param pInterface Pointer to the interface structure containing the called function pointer. 1373 * @param pStream Pointer to audio stream. 1374 */ 1375 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1376 1377 /** 1378 * Captures (reads from) an audio (input) stream. 1379 * 1380 * @returns VBox status code. 1381 * @param pInterface Pointer to the interface structure containing the called function pointer. 1382 * @param pStream Pointer to audio stream. 1383 * @param pvBuf Buffer where to store read audio data. 1384 * @param cbBuf Size of the audio data buffer in bytes. 1385 * @param pcbRead Where to return the number of bytes actually captured. 1386 */ 1387 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1388 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)); 1389 } PDMIHOSTAUDIO; 1390 1391 /** PDMIHOSTAUDIO interface ID. */ 1392 #define PDMIHOSTAUDIO_IID "c0875b91-a4f9-48be-8595-31d27048432d" 1393 1394 1395 /** Pointer to a audio notify from host interface. */ 1396 typedef struct PDMIHOSTAUDIOPORT *PPDMIHOSTAUDIOPORT; 1397 1398 /** 1399 * PDM host audio port interface, upwards sibling of PDMIHOSTAUDIO. 1400 */ 1401 typedef struct PDMIHOSTAUDIOPORT 1402 { 1403 /** 1404 * Ask DrvAudio to call PDMIHOSTAUDIO::pfnDoOnWorkerThread on a worker thread. 1405 * 1406 * Generic method for doing asynchronous work using the DrvAudio thread pool. 1407 * 1408 * This function will not wait for PDMIHOSTAUDIO::pfnDoOnWorkerThread to 1409 * complete, but returns immediately after submitting the request to the thread 1410 * pool. 1411 * 1412 * @returns VBox status code. 1413 * @param pInterface Pointer to this interface. 1414 * @param pStream Optional backend stream structure to pass along. The 1415 * reference count will be increased till the call 1416 * completes to make sure the stream stays valid. 1417 * @param uUser User specific value. 1418 * @param pvUser User specific pointer. 1419 */ 1420 DECLR3CALLBACKMEMBER(int, pfnDoOnWorkerThread,(PPDMIHOSTAUDIOPORT pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1421 uintptr_t uUser, void *pvUser)); 1422 1423 /** 1424 * The device for the given direction changed. 1425 * 1426 * The driver above backend (DrvAudio) will call the backend back 1427 * (PDMIHOSTAUDIO::pfnStreamNotifyDeviceChanged) for all open streams in the 1428 * given direction. (This ASSUMES the backend uses one output device and one 1429 * input devices for all streams.) 1430 * 1431 * @param pInterface Pointer to this interface. 1432 * @param enmDir The audio direction. 1433 * @param pvUser Backend specific parameter for 1434 * PDMIHOSTAUDIO::pfnStreamNotifyDeviceChanged. 1435 */ 1436 DECLR3CALLBACKMEMBER(void, pfnNotifyDeviceChanged,(PPDMIHOSTAUDIOPORT pInterface, PDMAUDIODIR enmDir, void *pvUser)); 1437 1438 /** 1439 * Notification that the stream is about to change device in a bit. 1440 * 1441 * This will assume PDMAUDIOSTREAM_STS_PREPARING_SWITCH will be set when 1442 * PDMIHOSTAUDIO::pfnStreamGetStatus is next called and change the stream state 1443 * accordingly. 1444 * 1445 * @param pInterface Pointer to this interface. 1446 * @param pStream The stream that changed device (backend variant). 1447 */ 1448 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyPreparingDeviceSwitch,(PPDMIHOSTAUDIOPORT pInterface, 1449 PPDMAUDIOBACKENDSTREAM pStream)); 1450 1451 /** 1452 * The stream has changed its device and left the 1453 * PDMAUDIOSTREAM_STS_PREPARING_SWITCH state (if it entered it at all). 1454 * 1455 * @param pInterface Pointer to this interface. 1456 * @param pStream The stream that changed device (backend variant). 1457 * @param fReInit Set if a re-init is required, clear if not. 1458 */ 1459 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyDeviceChanged,(PPDMIHOSTAUDIOPORT pInterface, 1460 PPDMAUDIOBACKENDSTREAM pStream, bool fReInit)); 1461 1462 /** 1463 * One or more audio devices have changed in some way. 1464 * 1465 * The upstream driver/device should re-evaluate the devices they're using. 1466 * 1467 * @todo r=bird: The upstream driver/device does not know which host audio 1468 * devices they are using. This is mainly for triggering enumeration and 1469 * logging of the audio devices. 1470 * 1471 * @param pInterface Pointer to this interface. 1472 */ 1473 DECLR3CALLBACKMEMBER(void, pfnNotifyDevicesChanged,(PPDMIHOSTAUDIOPORT pInterface)); 1474 } PDMIHOSTAUDIOPORT; 1475 1476 /** PDMIHOSTAUDIOPORT interface ID. */ 1477 #define PDMIHOSTAUDIOPORT_IID "92ea5169-8271-402d-99a7-9de26a52acaf" 1478 1479 1480 /** 693 1481 * Audio mixer controls. 1482 * 1483 * @note This isn't part of any official PDM interface as such, it's more of a 1484 * common thing that all the devices seem to need. 694 1485 */ 695 1486 typedef enum PDMAUDIOMIXERCTL … … 718 1509 719 1510 /** 720 * Audio stream commands.721 *722 * Used in the audio connector as well as in the actual host backends.723 */724 typedef enum PDMAUDIOSTREAMCMD725 {726 /** Invalid zero value as per usual (guards against using unintialized values). */727 PDMAUDIOSTREAMCMD_INVALID = 0,728 /** Enables the stream. */729 PDMAUDIOSTREAMCMD_ENABLE,730 /** Pauses the stream.731 * This is currently only issued when the VM is suspended (paused).732 * @remarks This is issued by DrvAudio, never by the mixer or devices. */733 PDMAUDIOSTREAMCMD_PAUSE,734 /** Resumes the stream.735 * This is currently only issued when the VM is resumed.736 * @remarks This is issued by DrvAudio, never by the mixer or devices. */737 PDMAUDIOSTREAMCMD_RESUME,738 /** Drain the stream, that is, play what's in the buffers and then stop.739 *740 * There will be no more samples written after this command is issued.741 * PDMIAUDIOCONNECTOR::pfnStreamIterate will drive progress for DrvAudio and742 * calls to PDMIHOSTAUDIO::pfnStreamPlay with a zero sized buffer will provide743 * the backend with a way to drive it forwards. These calls will come at a744 * frequency set by the device and be on an asynchronous I/O thread.745 *746 * A DISABLE command maybe submitted if the device/mixer wants to re-enable the747 * stream while it's still draining or if it gets impatient and thinks the748 * draining has been going on too long, in which case the stream should stop749 * immediately.750 *751 * @note This should not wait for the stream to finish draining, just change752 * the state. (The caller could be an EMT and it must not block for753 * hundreds of milliseconds of buffer to finish draining.)754 *755 * @note Does not apply to input streams. Backends should refuse such requests. */756 PDMAUDIOSTREAMCMD_DRAIN,757 /** Stops the stream immediately w/o any draining. */758 PDMAUDIOSTREAMCMD_DISABLE,759 /** End of valid values. */760 PDMAUDIOSTREAMCMD_END,761 /** Hack to blow the type up to 32-bit. */762 PDMAUDIOSTREAMCMD_32BIT_HACK = 0x7fffffff763 } PDMAUDIOSTREAMCMD;764 765 /**766 1511 * Audio volume parameters. 1512 * 1513 * @note This isn't part of any official PDM interface any more (it used to be 1514 * used to PDMIAUDIOCONNECTOR). It's currently only used by the mixer API. 767 1515 */ 768 1516 typedef struct PDMAUDIOVOLUME … … 770 1518 /** Set to @c true if this stream is muted, @c false if not. */ 771 1519 bool fMuted; 772 /** Left channel volume. 773 * Range is from [0 ... 255], whereas 0 specifies 774 * the most silent and 255 the loudest value. */ 775 uint8_t uLeft; 776 /** Right channel volume. 777 * Range is from [0 ... 255], whereas 0 specifies 778 * the most silent and 255 the loudest value. */ 779 uint8_t uRight; 1520 /** The volume for each channel. 1521 * The values zero is the most silent one (although not quite muted), and 255 1522 * the loudest. */ 1523 uint8_t auChannels[PDMAUDIO_MAX_CHANNELS]; 780 1524 } PDMAUDIOVOLUME; 781 1525 /** Pointer to audio volume settings. */ … … 788 1532 /** Defines the maximum volume allowed. */ 789 1533 #define PDMAUDIO_VOLUME_MAX (255) 790 791 792 /** 793 * Backend status. 794 */ 795 typedef enum PDMAUDIOBACKENDSTS 796 { 797 /** Unknown/invalid status. */ 798 PDMAUDIOBACKENDSTS_UNKNOWN = 0, 799 /** No backend attached. */ 800 PDMAUDIOBACKENDSTS_NOT_ATTACHED, 801 /** The backend is in its initialization phase. 802 * Not all backends support this status. */ 803 PDMAUDIOBACKENDSTS_INITIALIZING, 804 /** The backend has stopped its operation. */ 805 PDMAUDIOBACKENDSTS_STOPPED, 806 /** The backend is up and running. */ 807 PDMAUDIOBACKENDSTS_RUNNING, 808 /** The backend ran into an error and is unable to recover. 809 * A manual re-initialization might help. */ 810 PDMAUDIOBACKENDSTS_ERROR, 811 /** Hack to blow the type up to 32-bit. */ 812 PDMAUDIOBACKENDSTS_32BIT_HACK = 0x7fffffff 813 } PDMAUDIOBACKENDSTS; 814 815 /** 816 * PDM audio stream state. 817 * 818 * This is all the mixer/device needs. The PDMAUDIOSTREAM_STS_XXX stuff will 819 * become DrvAudio internal state once the backend stuff is destilled out of it. 820 * 821 * @note The value order is significant, don't change it willy-nilly. 822 */ 823 typedef enum PDMAUDIOSTREAMSTATE 824 { 825 /** Invalid state value. */ 826 PDMAUDIOSTREAMSTATE_INVALID = 0, 827 /** The stream is not operative and cannot be enabled. */ 828 PDMAUDIOSTREAMSTATE_NOT_WORKING, 829 /** The stream needs to be re-initialized by the device/mixer 830 * (i.e. call PDMIAUDIOCONNECTOR::pfnStreamReInit). */ 831 PDMAUDIOSTREAMSTATE_NEED_REINIT, 832 /** The stream is inactive (not enabled). */ 833 PDMAUDIOSTREAMSTATE_INACTIVE, 834 /** The stream is enabled but nothing to read/write. 835 * @todo not sure if we need this variant... */ 836 PDMAUDIOSTREAMSTATE_ENABLED, 837 /** The stream is enabled and captured samples can be read. */ 838 PDMAUDIOSTREAMSTATE_ENABLED_READABLE, 839 /** The stream is enabled and samples can be written for playback. */ 840 PDMAUDIOSTREAMSTATE_ENABLED_WRITABLE, 841 /** End of valid states. */ 842 PDMAUDIOSTREAMSTATE_END, 843 /** Make sure the type is 32-bit wide. */ 844 PDMAUDIOSTREAMSTATE_32BIT_HACK = 0x7fffffff 845 } PDMAUDIOSTREAMSTATE; 846 847 /** @name PDMAUDIOSTREAM_CREATE_F_XXX 848 * @{ */ 849 /** Does not need any mixing buffers, the device takes care of all conversion. 850 * @note this is now default and assumed always set. */ 851 #define PDMAUDIOSTREAM_CREATE_F_NO_MIXBUF RT_BIT_32(0) 1534 /** Initializator for max volume on all channels. */ 1535 #define PDMAUDIOVOLUME_INITIALIZER_MAX \ 1536 { /* .fMuted = */ false, \ 1537 /* .auChannels = */ { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } 1538 852 1539 /** @} */ 853 1540 854 /** @name PDMAUDIOSTREAM_WARN_FLAGS_XXX855 * @{ */856 /** No stream warning flags set. */857 #define PDMAUDIOSTREAM_WARN_FLAGS_NONE 0858 /** Warned about a disabled stream. */859 #define PDMAUDIOSTREAM_WARN_FLAGS_DISABLED RT_BIT(0)860 /** @} */861 862 /**863 * An input or output audio stream.864 */865 typedef struct PDMAUDIOSTREAM866 {867 /** Critical section protecting the stream.868 *869 * When not otherwise stated, DrvAudio will enter this before calling the870 * backend. The backend and device/mixer can normally safely enter it prior to871 * a DrvAudio call, however not to pfnStreamDestroy, pfnStreamRelease or872 * anything that may access the stream list.873 *874 * @note Lock ordering:875 * - After DRVAUDIO::CritSectGlobals.876 * - Before DRVAUDIO::CritSectHotPlug. */877 RTCRITSECT CritSect;878 /** Stream configuration. */879 PDMAUDIOSTREAMCFG Cfg;880 /** Magic value (PDMAUDIOSTREAM_MAGIC). */881 uint32_t uMagic;882 /** Size (in bytes) of the backend-specific stream data. */883 uint32_t cbBackend;884 /** Warnings shown already in the release log.885 * See PDMAUDIOSTREAM_WARN_FLAGS_XXX. */886 uint32_t fWarningsShown;887 } PDMAUDIOSTREAM;888 /** Pointer to an audio stream. */889 typedef struct PDMAUDIOSTREAM *PPDMAUDIOSTREAM;890 /** Pointer to a const audio stream. */891 typedef struct PDMAUDIOSTREAM const *PCPDMAUDIOSTREAM;892 893 /** Magic value for PDMAUDIOSTREAM. */894 #define PDMAUDIOSTREAM_MAGIC PDM_VERSION_MAKE(0xa0d3, 5, 0)895 896 897 898 /** Pointer to a audio connector interface. */899 typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;900 901 /**902 * Audio connector interface (up).903 */904 typedef struct PDMIAUDIOCONNECTOR905 {906 /**907 * Enables or disables the given audio direction for this driver.908 *909 * When disabled, assiociated output streams consume written audio without passing them further down to the backends.910 * Associated input streams then return silence when read from those.911 *912 * @returns VBox status code.913 * @param pInterface Pointer to the interface structure containing the called function pointer.914 * @param enmDir Audio direction to enable or disable driver for.915 * @param fEnable Whether to enable or disable the specified audio direction.916 *917 * @note Be very careful when using this function, as this could918 * violate / run against the (global) VM settings. See @bugref{9882}.919 */920 DECLR3CALLBACKMEMBER(int, pfnEnable, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir, bool fEnable));921 922 /**923 * Returns whether the given audio direction for this driver is enabled or not.924 *925 * @returns True if audio is enabled for the given direction, false if not.926 * @param pInterface Pointer to the interface structure containing the called function pointer.927 * @param enmDir Audio direction to retrieve enabled status for.928 */929 DECLR3CALLBACKMEMBER(bool, pfnIsEnabled, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir));930 931 /**932 * Retrieves the current configuration of the host audio backend.933 *934 * @returns VBox status code.935 * @param pInterface Pointer to the interface structure containing the called function pointer.936 * @param pCfg Where to store the host audio backend configuration data.937 */938 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOBACKENDCFG pCfg));939 940 /**941 * Retrieves the current status of the host audio backend.942 *943 * @returns Status of the host audio backend.944 * @param pInterface Pointer to the interface structure containing the called function pointer.945 * @param enmDir Audio direction to check host audio backend for. Specify PDMAUDIODIR_DUPLEX for the overall946 * backend status.947 */948 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir));949 950 /**951 * Gives the audio drivers a hint about a typical configuration.952 *953 * This is a little hack for windows (and maybe other hosts) where stream954 * creation can take a relatively long time, making it very unsuitable for EMT.955 * The audio backend can use this hint to cache pre-configured stream setups,956 * so that when the guest actually wants to play something EMT won't be blocked957 * configuring host audio.958 *959 * @param pInterface Pointer to this interface.960 * @param pCfg The typical configuration. Can be modified by the961 * drivers in unspecified ways.962 */963 DECLR3CALLBACKMEMBER(void, pfnStreamConfigHint, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg));964 965 /**966 * Creates an audio stream.967 *968 * @returns VBox status code.969 * @param pInterface Pointer to this interface.970 * @param fFlags PDMAUDIOSTREAM_CREATE_F_XXX.971 * @param pCfgReq The requested stream configuration. The actual stream972 * configuration can be found in pStream->Cfg on success.973 * @param ppStream Pointer where to return the created audio stream on974 * success.975 */976 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, uint32_t fFlags, PCPDMAUDIOSTREAMCFG pCfgReq,977 PPDMAUDIOSTREAM *ppStream));978 979 980 /**981 * Destroys an audio stream.982 *983 * @param pInterface Pointer to the interface structure containing the called function pointer.984 * @param pStream Pointer to audio stream.985 * @param fImmediate Whether to immdiately stop and destroy a draining986 * stream (@c true), or to allow it to complete987 * draining first (@c false) if that's feasable.988 * The latter depends on the draining stage and what989 * the backend is capable of.990 */991 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, bool fImmediate));992 993 /**994 * Re-initializes the stream in response to PDMAUDIOSTREAM_STS_NEED_REINIT.995 *996 * @returns VBox status code.997 * @param pInterface Pointer to this interface.998 * @param pStream The audio stream needing re-initialization.999 */1000 DECLR3CALLBACKMEMBER(int, pfnStreamReInit, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));1001 1002 /**1003 * Adds a reference to the specified audio stream.1004 *1005 * @returns New reference count. UINT32_MAX on error.1006 * @param pInterface Pointer to the interface structure containing the called function pointer.1007 * @param pStream Pointer to audio stream adding the reference to.1008 */1009 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRetain, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));1010 1011 /**1012 * Releases a reference from the specified stream.1013 *1014 * @returns New reference count. UINT32_MAX on error.1015 * @param pInterface Pointer to the interface structure containing the called function pointer.1016 * @param pStream Pointer to audio stream releasing a reference from.1017 */1018 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRelease, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));1019 1020 /**1021 * Controls a specific audio stream.1022 *1023 * @returns VBox status code.1024 * @param pInterface Pointer to the interface structure containing the called function pointer.1025 * @param pStream Pointer to audio stream.1026 * @param enmStreamCmd The stream command to issue.1027 */1028 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,1029 PDMAUDIOSTREAMCMD enmStreamCmd));1030 1031 /**1032 * Processes stream data.1033 *1034 * @param pInterface Pointer to the interface structure containing the called function pointer.1035 * @param pStream Pointer to audio stream.1036 */1037 DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));1038 1039 /**1040 * Returns the state of a specific audio stream (destilled status).1041 *1042 * @returns PDMAUDIOSTREAMSTATE value.1043 * @retval PDMAUDIOSTREAMSTATE_INVALID if the input isn't valid (w/ assertion).1044 * @param pInterface Pointer to the interface structure containing the called function pointer.1045 * @param pStream Pointer to audio stream.1046 */1047 DECLR3CALLBACKMEMBER(PDMAUDIOSTREAMSTATE, pfnStreamGetState, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));1048 1049 /**1050 * Returns the number of bytes that can be written to an audio output stream.1051 *1052 * @returns Number of bytes writable data.1053 * @param pInterface Pointer to the interface structure containing the called function pointer.1054 * @param pStream Pointer to audio stream.1055 */1056 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));1057 1058 /**1059 * Plays (writes to) an audio output stream.1060 *1061 * @returns VBox status code.1062 * @param pInterface Pointer to the interface structure containing the called function pointer.1063 * @param pStream Pointer to audio stream to read from.1064 * @param pvBuf Audio data to be written.1065 * @param cbBuf Number of bytes to be written.1066 * @param pcbWritten Bytes of audio data written. Optional.1067 */1068 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,1069 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));1070 1071 /**1072 * Returns the number of bytes that can be read from an input stream.1073 *1074 * @returns Number of bytes of readable data.1075 * @param pInterface Pointer to the interface structure containing the called function pointer.1076 * @param pStream Pointer to audio stream.1077 */1078 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));1079 1080 /**1081 * Captures (reads) samples from an audio input stream.1082 *1083 * @returns VBox status code.1084 * @param pInterface Pointer to the interface structure containing the called function pointer.1085 * @param pStream Pointer to audio stream to write to.1086 * @param pvBuf Where to store the read data.1087 * @param cbBuf Number of bytes to read.1088 * @param pcbRead Bytes of audio data read. Optional.1089 */1090 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,1091 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));1092 } PDMIAUDIOCONNECTOR;1093 1094 /** PDMIAUDIOCONNECTOR interface ID. */1095 #define PDMIAUDIOCONNECTOR_IID "2900fe2a-6aeb-4953-ac12-f8965612f446"1096 1097 1098 /**1099 * Host audio backend specific stream data.1100 *1101 * The backend will put this as the first member of it's own data structure.1102 */1103 typedef struct PDMAUDIOBACKENDSTREAM1104 {1105 /** Magic value (PDMAUDIOBACKENDSTREAM_MAGIC). */1106 uint32_t uMagic;1107 /** Explicit zero padding - do not touch! */1108 uint32_t uReserved;1109 /** Pointer to the stream this backend data is associated with. */1110 PPDMAUDIOSTREAM pStream;1111 /** Reserved for future use (zeroed) - do not touch. */1112 void *apvReserved[2];1113 } PDMAUDIOBACKENDSTREAM;1114 /** Pointer to host audio specific stream data! */1115 typedef PDMAUDIOBACKENDSTREAM *PPDMAUDIOBACKENDSTREAM;1116 1117 /** Magic value for PDMAUDIOBACKENDSTREAM. */1118 #define PDMAUDIOBACKENDSTREAM_MAGIC PDM_VERSION_MAKE(0xa0d4, 1, 0)1119 1120 /**1121 * Host audio (backend) stream state returned by PDMIHOSTAUDIO::pfnStreamGetState.1122 */1123 typedef enum PDMHOSTAUDIOSTREAMSTATE1124 {1125 /** Invalid zero value, as per usual. */1126 PDMHOSTAUDIOSTREAMSTATE_INVALID = 0,1127 /** The stream is being initialized.1128 * This should also be used when switching to a new device and the stream1129 * stops to work with the old device while the new one being configured. */1130 PDMHOSTAUDIOSTREAMSTATE_INITIALIZING,1131 /** The stream does not work (async init failed, audio subsystem gone1132 * fishing, or similar). */1133 PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING,1134 /** Backend is working okay. */1135 PDMHOSTAUDIOSTREAMSTATE_OKAY,1136 /** Backend is working okay, but currently draining the stream. */1137 PDMHOSTAUDIOSTREAMSTATE_DRAINING,1138 /** Backend is working but doesn't want any commands or data reads/writes. */1139 PDMHOSTAUDIOSTREAMSTATE_INACTIVE,1140 /** End of valid values. */1141 PDMHOSTAUDIOSTREAMSTATE_END,1142 /** Blow the type up to 32 bits. */1143 PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK = 0x7fffffff1144 } PDMHOSTAUDIOSTREAMSTATE;1145 1146 1147 /** Pointer to a host audio interface. */1148 typedef struct PDMIHOSTAUDIO *PPDMIHOSTAUDIO;1149 1150 /**1151 * PDM host audio interface.1152 */1153 typedef struct PDMIHOSTAUDIO1154 {1155 /**1156 * Returns the host backend's configuration (backend).1157 *1158 * @returns VBox status code.1159 * @param pInterface Pointer to the interface structure containing the called function pointer.1160 * @param pBackendCfg Where to store the backend audio configuration to.1161 */1162 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg));1163 1164 /**1165 * Returns (enumerates) host audio device information (optional).1166 *1167 * @returns VBox status code.1168 * @param pInterface Pointer to the interface structure containing the called function pointer.1169 * @param pDeviceEnum Where to return the enumerated audio devices.1170 */1171 DECLR3CALLBACKMEMBER(int, pfnGetDevices, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum));1172 1173 /**1174 * Changes the output or input device.1175 *1176 * @returns VBox status code.1177 * @param pInterface Pointer to this interface.1178 * @param enmDir The direction to set the device for: PDMAUDIODIR_IN,1179 * PDMAUDIODIR_OUT or PDMAUDIODIR_DUPLEX (both the1180 * previous).1181 * @param pszId The PDMAUDIOHOSTDEV::pszId value of the device to1182 * use, or NULL / empty string for the default device.1183 */1184 DECLR3CALLBACKMEMBER(int, pfnSetDevice, (PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir, const char *pszId));1185 1186 /**1187 * Returns the current status from the audio backend (optional).1188 *1189 * @returns PDMAUDIOBACKENDSTS enum.1190 * @param pInterface Pointer to the interface structure containing the called function pointer.1191 * @param enmDir Audio direction to get status for. Pass PDMAUDIODIR_DUPLEX for overall status.1192 */1193 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir));1194 1195 /**1196 * Callback for genric on-worker-thread requests initiated by the backend itself.1197 *1198 * This is the counterpart to PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread that will1199 * be invoked on a worker thread when the backend requests it - optional.1200 *1201 * This does not return a value, so the backend must keep track of1202 * failure/success on its own.1203 *1204 * This method is optional. A non-NULL will, together with pfnStreamInitAsync1205 * and PDMAUDIOBACKEND_F_ASYNC_HINT, force DrvAudio to create the thread pool.1206 *1207 * @param pInterface Pointer to this interface.1208 * @param pStream Optionally a backend stream if specified in the1209 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.1210 * @param uUser User specific value as specified in the1211 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.1212 * @param pvUser User specific pointer as specified in the1213 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.1214 */1215 DECLR3CALLBACKMEMBER(void, pfnDoOnWorkerThread,(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,1216 uintptr_t uUser, void *pvUser));1217 1218 /**1219 * Gives the audio backend a hint about a typical configuration (optional).1220 *1221 * This is a little hack for windows (and maybe other hosts) where stream1222 * creation can take a relatively long time, making it very unsuitable for EMT.1223 * The audio backend can use this hint to cache pre-configured stream setups,1224 * so that when the guest actually wants to play something EMT won't be blocked1225 * configuring host audio.1226 *1227 * The backend can return PDMAUDIOBACKEND_F_ASYNC_HINT in1228 * PDMIHOSTAUDIO::pfnGetConfig to avoid having EMT making this call and thereby1229 * speeding up VM construction.1230 *1231 * @param pInterface Pointer to this interface.1232 * @param pCfg The typical configuration. (Feel free to change it1233 * to the actual stream config that would be used,1234 * however caller will probably ignore this.)1235 */1236 DECLR3CALLBACKMEMBER(void, pfnStreamConfigHint, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAMCFG pCfg));1237 1238 /**1239 * Creates an audio stream using the requested stream configuration.1240 *1241 * If a backend is not able to create this configuration, it will return its1242 * best match in the acquired configuration structure on success.1243 *1244 * @returns VBox status code.1245 * @retval VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED if1246 * PDMIHOSTAUDIO::pfnStreamInitAsync should be called.1247 * @param pInterface Pointer to this interface.1248 * @param pStream Pointer to the audio stream.1249 * @param pCfgReq The requested stream configuration.1250 * @param pCfgAcq The acquired stream configuration - output. This is1251 * the same as @a *pCfgReq when called, the1252 * implementation will adjust it to make the actual1253 * stream configuration as needed.1254 */1255 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,1256 PCPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq));1257 1258 /**1259 * Asynchronous stream initialization step, optional.1260 *1261 * This is called on a worker thread iff the PDMIHOSTAUDIO::pfnStreamCreate1262 * method returns VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED.1263 *1264 * @returns VBox status code.1265 * @param pInterface Pointer to this interface.1266 * @param pStream Pointer to audio stream to continue1267 * initialization of.1268 * @param fDestroyed Set to @c true if the stream has been destroyed1269 * before the worker thread got to making this1270 * call. The backend should just ready the stream1271 * for destruction in that case.1272 */1273 DECLR3CALLBACKMEMBER(int, pfnStreamInitAsync, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fDestroyed));1274 1275 /**1276 * Destroys an audio stream.1277 *1278 * @returns VBox status code.1279 * @param pInterface Pointer to the interface containing the called function.1280 * @param pStream Pointer to audio stream.1281 * @param fImmediate Whether to immdiately stop and destroy a draining1282 * stream (@c true), or to allow it to complete1283 * draining first (@c false) if that's feasable.1284 */1285 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fImmediate));1286 1287 /**1288 * Called from PDMIHOSTAUDIOPORT::pfnNotifyDeviceChanged so the backend can start1289 * the device change for a stream.1290 *1291 * This is mainly to avoid the need for a list of streams in the backend.1292 *1293 * @param pInterface Pointer to this interface.1294 * @param pStream Pointer to audio stream (locked).1295 * @param pvUser Backend specific parameter from the call to1296 * PDMIHOSTAUDIOPORT::pfnNotifyDeviceChanged.1297 */1298 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyDeviceChanged,(PPDMIHOSTAUDIO pInterface,1299 PPDMAUDIOBACKENDSTREAM pStream, void *pvUser));1300 1301 /**1302 * Enables (starts) the stream.1303 *1304 * @returns VBox status code.1305 * @param pInterface Pointer to this interface.1306 * @param pStream Pointer to the audio stream to enable.1307 * @sa PDMAUDIOSTREAMCMD_ENABLE1308 */1309 DECLR3CALLBACKMEMBER(int, pfnStreamEnable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1310 1311 /**1312 * Disables (stops) the stream immediately.1313 *1314 * @returns VBox status code.1315 * @param pInterface Pointer to this interface.1316 * @param pStream Pointer to the audio stream to disable.1317 * @sa PDMAUDIOSTREAMCMD_DISABLE1318 */1319 DECLR3CALLBACKMEMBER(int, pfnStreamDisable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1320 1321 /**1322 * Pauses the stream - called when the VM is suspended.1323 *1324 * @returns VBox status code.1325 * @param pInterface Pointer to this interface.1326 * @param pStream Pointer to the audio stream to pause.1327 * @sa PDMAUDIOSTREAMCMD_PAUSE1328 */1329 DECLR3CALLBACKMEMBER(int, pfnStreamPause, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1330 1331 /**1332 * Resumes a paused stream - called when the VM is resumed.1333 *1334 * @returns VBox status code.1335 * @param pInterface Pointer to this interface.1336 * @param pStream Pointer to the audio stream to resume.1337 * @sa PDMAUDIOSTREAMCMD_RESUME1338 */1339 DECLR3CALLBACKMEMBER(int, pfnStreamResume, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1340 1341 /**1342 * Drain the stream, that is, play what's in the buffers and then stop.1343 *1344 * There will be no more samples written after this command is issued.1345 * PDMIHOSTAUDIO::pfnStreamPlay with a zero sized buffer will provide the1346 * backend with a way to drive it forwards. These calls will come at a1347 * frequency set by the device and be on an asynchronous I/O thread.1348 *1349 * The PDMIHOSTAUDIO::pfnStreamDisable method maybe called if the device/mixer1350 * wants to re-enable the stream while it's still draining or if it gets1351 * impatient and thinks the draining has been going on too long, in which case1352 * the stream should stop immediately.1353 *1354 * @note This should not wait for the stream to finish draining, just change1355 * the state. (The caller could be an EMT and it must not block for1356 * hundreds of milliseconds of buffer to finish draining.)1357 *1358 * @note Does not apply to input streams. Backends should refuse such1359 * requests.1360 *1361 * @returns VBox status code.1362 * @retval VERR_WRONG_ORDER if not output stream.1363 * @param pInterface Pointer to this interface.1364 * @param pStream Pointer to the audio stream to drain.1365 * @sa PDMAUDIOSTREAMCMD_DRAIN1366 */1367 DECLR3CALLBACKMEMBER(int, pfnStreamDrain, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1368 1369 /**1370 * Returns the current state of the given backend stream.1371 *1372 * @returns PDMHOSTAUDIOSTREAMSTATE value.1373 * @retval PDMHOSTAUDIOSTREAMSTATE_INVALID if invalid stream.1374 * @param pInterface Pointer to the interface structure containing the called function pointer.1375 * @param pStream Pointer to audio stream.1376 */1377 DECLR3CALLBACKMEMBER(PDMHOSTAUDIOSTREAMSTATE, pfnStreamGetState, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1378 1379 /**1380 * Returns the number of buffered bytes that hasn't been played yet (optional).1381 *1382 * Is not valid on an input stream, implementions shall assert and return zero.1383 *1384 * @returns Number of pending bytes.1385 * @param pInterface Pointer to this interface.1386 * @param pStream Pointer to the audio stream.1387 *1388 * @todo This is no longer not used by DrvAudio and can probably be removed.1389 */1390 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetPending, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1391 1392 /**1393 * Returns the amount which is writable to the audio (output) stream.1394 *1395 * @returns Number of writable bytes.1396 * @param pInterface Pointer to the interface structure containing the called function pointer.1397 * @param pStream Pointer to audio stream.1398 */1399 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1400 1401 /**1402 * Plays (writes to) an audio (output) stream.1403 *1404 * This is always called with data in the buffer, except after1405 * PDMAUDIOSTREAMCMD_DRAIN is issued when it's called every so often to assist1406 * the backend with moving the draining operation forward (kind of like1407 * PDMIAUDIOCONNECTOR::pfnStreamIterate).1408 *1409 * @returns VBox status code.1410 * @param pInterface Pointer to the interface structure containing the called function pointer.1411 * @param pStream Pointer to audio stream.1412 * @param pvBuf Pointer to audio data buffer to play. This will be NULL1413 * when called to assist draining the stream.1414 * @param cbBuf The number of bytes of audio data to play. This will be1415 * zero when called to assist draining the stream.1416 * @param pcbWritten Where to return the actual number of bytes played.1417 */1418 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,1419 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));1420 1421 /**1422 * Returns the amount which is readable from the audio (input) stream.1423 *1424 * @returns For non-raw layout streams: Number of readable bytes.1425 * for raw layout streams : Number of readable audio frames.1426 * @param pInterface Pointer to the interface structure containing the called function pointer.1427 * @param pStream Pointer to audio stream.1428 */1429 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));1430 1431 /**1432 * Captures (reads from) an audio (input) stream.1433 *1434 * @returns VBox status code.1435 * @param pInterface Pointer to the interface structure containing the called function pointer.1436 * @param pStream Pointer to audio stream.1437 * @param pvBuf Buffer where to store read audio data.1438 * @param cbBuf Size of the audio data buffer in bytes.1439 * @param pcbRead Where to return the number of bytes actually captured.1440 */1441 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,1442 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));1443 } PDMIHOSTAUDIO;1444 1445 /** PDMIHOSTAUDIO interface ID. */1446 #define PDMIHOSTAUDIO_IID "c0875b91-a4f9-48be-8595-31d27048432d"1447 1448 1449 /** Pointer to a audio notify from host interface. */1450 typedef struct PDMIHOSTAUDIOPORT *PPDMIHOSTAUDIOPORT;1451 1452 /**1453 * PDM host audio port interface, upwards sibling of PDMIHOSTAUDIO.1454 */1455 typedef struct PDMIHOSTAUDIOPORT1456 {1457 /**1458 * Ask DrvAudio to call PDMIHOSTAUDIO::pfnDoOnWorkerThread on a worker thread.1459 *1460 * Generic method for doing asynchronous work using the DrvAudio thread pool.1461 *1462 * This function will not wait for PDMIHOSTAUDIO::pfnDoOnWorkerThread to1463 * complete, but returns immediately after submitting the request to the thread1464 * pool.1465 *1466 * @returns VBox status code.1467 * @param pInterface Pointer to this interface.1468 * @param pStream Optional backend stream structure to pass along. The1469 * reference count will be increased till the call1470 * completes to make sure the stream stays valid.1471 * @param uUser User specific value.1472 * @param pvUser User specific pointer.1473 */1474 DECLR3CALLBACKMEMBER(int, pfnDoOnWorkerThread,(PPDMIHOSTAUDIOPORT pInterface, PPDMAUDIOBACKENDSTREAM pStream,1475 uintptr_t uUser, void *pvUser));1476 1477 /**1478 * The device for the given direction changed.1479 *1480 * The driver above backend (DrvAudio) will call the backend back1481 * (PDMIHOSTAUDIO::pfnStreamNotifyDeviceChanged) for all open streams in the1482 * given direction. (This ASSUMES the backend uses one output device and one1483 * input devices for all streams.)1484 *1485 * @param pInterface Pointer to this interface.1486 * @param enmDir The audio direction.1487 * @param pvUser Backend specific parameter for1488 * PDMIHOSTAUDIO::pfnStreamNotifyDeviceChanged.1489 */1490 DECLR3CALLBACKMEMBER(void, pfnNotifyDeviceChanged,(PPDMIHOSTAUDIOPORT pInterface, PDMAUDIODIR enmDir, void *pvUser));1491 1492 /**1493 * Notification that the stream is about to change device in a bit.1494 *1495 * This will assume PDMAUDIOSTREAM_STS_PREPARING_SWITCH will be set when1496 * PDMIHOSTAUDIO::pfnStreamGetStatus is next called and change the stream state1497 * accordingly.1498 *1499 * @param pInterface Pointer to this interface.1500 * @param pStream The stream that changed device (backend variant).1501 */1502 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyPreparingDeviceSwitch,(PPDMIHOSTAUDIOPORT pInterface,1503 PPDMAUDIOBACKENDSTREAM pStream));1504 1505 /**1506 * The stream has changed its device and left the1507 * PDMAUDIOSTREAM_STS_PREPARING_SWITCH state (if it entered it at all).1508 *1509 * @param pInterface Pointer to this interface.1510 * @param pStream The stream that changed device (backend variant).1511 * @param fReInit Set if a re-init is required, clear if not.1512 */1513 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyDeviceChanged,(PPDMIHOSTAUDIOPORT pInterface,1514 PPDMAUDIOBACKENDSTREAM pStream, bool fReInit));1515 1516 /**1517 * One or more audio devices have changed in some way.1518 *1519 * The upstream driver/device should re-evaluate the devices they're using.1520 *1521 * @todo r=bird: The upstream driver/device does not know which host audio1522 * devices they are using. This is mainly for triggering enumeration and1523 * logging of the audio devices.1524 *1525 * @param pInterface Pointer to this interface.1526 */1527 DECLR3CALLBACKMEMBER(void, pfnNotifyDevicesChanged,(PPDMIHOSTAUDIOPORT pInterface));1528 } PDMIHOSTAUDIOPORT;1529 1530 /** PDMIHOSTAUDIOPORT interface ID. */1531 #define PDMIHOSTAUDIOPORT_IID "92ea5169-8271-402d-99a7-9de26a52acaf"1532 1533 /** @} */1534 1535 1541 RT_C_DECLS_END 1536 1542 -
trunk/include/VBox/vmm/pdmaudioinline.h
r89569 r89768 182 182 183 183 /********************************************************************************************************************************* 184 * Volume Helpers * 185 *********************************************************************************************************************************/ 186 187 /** 188 * Initializes a PDMAUDIOVOLUME structure to max. 189 * 190 * @param pVol The structure to initialize. 191 */ 192 DECLINLINE(void) PDMAudioVolumeInitMax(PPDMAUDIOVOLUME pVol) 193 { 194 pVol->fMuted = false; 195 for (uintptr_t i = 0; i < RT_ELEMENTS(pVol->auChannels); i++) 196 pVol->auChannels[i] = PDMAUDIO_VOLUME_MAX; 197 } 198 199 200 /** 201 * Initializes a PDMAUDIOVOLUME structure from a simple stereo setting. 202 * 203 * The additional channels will simply be assigned the higer of the two. 204 * 205 * @param pVol The structure to initialize. 206 * @param fMuted Muted. 207 * @param bLeft The left channel volume. 208 * @param bRight The right channel volume. 209 */ 210 DECLINLINE(void) PDMAudioVolumeInitFromStereo(PPDMAUDIOVOLUME pVol, bool fMuted, uint8_t bLeft, uint8_t bRight) 211 { 212 pVol->fMuted = fMuted; 213 pVol->auChannels[0] = bLeft; 214 pVol->auChannels[1] = bRight; 215 216 uint8_t const bOther = RT_MAX(bLeft, bRight); 217 for (uintptr_t i = 2; i < RT_ELEMENTS(pVol->auChannels); i++) 218 pVol->auChannels[i] = bOther; 219 } 220 221 222 /** 223 * Combines two volume settings (typically master and sink). 224 * 225 * @param pVol Where to return the combined volume 226 * @param pVol1 The first volume settings to combine. 227 * @param pVol2 The second volume settings. 228 */ 229 DECLINLINE(void) PDMAudioVolumeCombine(PPDMAUDIOVOLUME pVol, PCPDMAUDIOVOLUME pVol1, PCPDMAUDIOVOLUME pVol2) 230 { 231 if (pVol1->fMuted || pVol2->fMuted) 232 { 233 pVol->fMuted = true; 234 for (uintptr_t i = 0; i < RT_ELEMENTS(pVol->auChannels); i++) 235 pVol->auChannels[i] = 0; 236 } 237 else 238 { 239 pVol->fMuted = false; 240 /** @todo Very crude implementation for now -- needs more work! (At least 241 * when used in audioMixerSinkUpdateVolume it was considered as such.) */ 242 for (uintptr_t i = 0; i < RT_ELEMENTS(pVol->auChannels); i++) 243 { 244 #if 0 /* bird: I think the shift variant should produce the exact same result, w/o two conditionals per iteration. */ 245 /* 255 * 255 / 255 = 0xFF (255) */ 246 /* 17 * 127 / 255 = 8 */ 247 /* 39 * 39 / 255 = 5 */ 248 pVol->auChannels[i] = (uint8_t)( (RT_MAX(pVol1->auChannels[i], 1U) * RT_MAX(pVol2->auChannels[i], 1U)) 249 / PDMAUDIO_VOLUME_MAX); 250 #else 251 /* (((255 + 1) * (255 + 1)) >> 8) - 1 = 0xFF (255) */ 252 /* ((( 17 + 1) * (127 + 1)) >> 8) - 1 = 0x8 (8) */ 253 /* ((( 39 + 1) * ( 39 + 1)) >> 8) - 1 = 0x5 (5) */ 254 pVol->auChannels[i] = (uint8_t)((((1U + pVol1->auChannels[i]) * (1U + pVol2->auChannels[i])) >> 8) - 1U); 255 #endif 256 } 257 } 258 } 259 260 261 /********************************************************************************************************************************* 184 262 * PCM Property Helpers * 185 263 *********************************************************************************************************************************/
Note:
See TracChangeset
for help on using the changeset viewer.