VirtualBox

Changeset 89768 in vbox for trunk/include


Ignore:
Timestamp:
Jun 17, 2021 11:03:19 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145220
Message:

Audio: Made PDMAUDIOVOLUME multichannel. bugref:9890

Location:
trunk/include/VBox/vmm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmaudioifs.h

    r89510 r89768  
    691691
    692692/**
     693 * Audio stream commands.
     694 *
     695 * Used in the audio connector as well as in the actual host backends.
     696 */
     697typedef 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 */
     741typedef 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 */
     769typedef 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 */
     811typedef 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. */
     835typedef struct PDMAUDIOSTREAM *PPDMAUDIOSTREAM;
     836/** Pointer to a const audio stream. */
     837typedef 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. */
     845typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;
     846
     847/**
     848 * Audio connector interface (up).
     849 */
     850typedef 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 */
     1049typedef 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! */
     1061typedef 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 */
     1069typedef 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. */
     1094typedef struct PDMIHOSTAUDIO *PPDMIHOSTAUDIO;
     1095
     1096/**
     1097 * PDM host audio interface.
     1098 */
     1099typedef 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. */
     1396typedef struct PDMIHOSTAUDIOPORT *PPDMIHOSTAUDIOPORT;
     1397
     1398/**
     1399 * PDM host audio port interface, upwards sibling of PDMIHOSTAUDIO.
     1400 */
     1401typedef 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/**
    6931481 * 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.
    6941485 */
    6951486typedef enum PDMAUDIOMIXERCTL
     
    7181509
    7191510/**
    720  * Audio stream commands.
    721  *
    722  * Used in the audio connector as well as in the actual host backends.
    723  */
    724 typedef enum PDMAUDIOSTREAMCMD
    725 {
    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 and
    742      * calls to PDMIHOSTAUDIO::pfnStreamPlay with a zero sized buffer will provide
    743      * the backend with a way to drive it forwards.  These calls will come at a
    744      * 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 the
    747      * stream while it's still draining or if it gets impatient and thinks the
    748      * draining has been going on too long, in which case the stream should stop
    749      * immediately.
    750      *
    751      * @note    This should not wait for the stream to finish draining, just change
    752      *          the state.  (The caller could be an EMT and it must not block for
    753      *          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 = 0x7fffffff
    763 } PDMAUDIOSTREAMCMD;
    764 
    765 /**
    7661511 * 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.
    7671515 */
    7681516typedef struct PDMAUDIOVOLUME
     
    7701518    /** Set to @c true if this stream is muted, @c false if not. */
    7711519    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];
    7801524} PDMAUDIOVOLUME;
    7811525/** Pointer to audio volume settings. */
     
    7881532/** Defines the maximum volume allowed. */
    7891533#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
    8521539/** @} */
    8531540
    854 /** @name PDMAUDIOSTREAM_WARN_FLAGS_XXX
    855  * @{ */
    856 /** No stream warning flags set. */
    857 #define PDMAUDIOSTREAM_WARN_FLAGS_NONE          0
    858 /** 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 PDMAUDIOSTREAM
    866 {
    867     /** Critical section protecting the stream.
    868      *
    869      * When not otherwise stated, DrvAudio will enter this before calling the
    870      * backend.   The backend and device/mixer can normally safely enter it prior to
    871      * a DrvAudio call, however not to pfnStreamDestroy, pfnStreamRelease or
    872      * 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 PDMIAUDIOCONNECTOR
    905 {
    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 could
    918      *          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 overall
    946      *                          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 stream
    954      * 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 blocked
    957      * configuring host audio.
    958      *
    959      * @param   pInterface  Pointer to this interface.
    960      * @param   pCfg        The typical configuration.  Can be modified by the
    961      *                      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 stream
    972      *                      configuration can be found in pStream->Cfg on success.
    973      * @param   ppStream    Pointer where to return the created audio stream on
    974      *                      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 draining
    986      *                          stream (@c true), or to allow it to complete
    987      *                          draining first (@c false) if that's feasable.
    988      *                          The latter depends on the draining stage and what
    989      *                          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 PDMAUDIOBACKENDSTREAM
    1104 {
    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 PDMHOSTAUDIOSTREAMSTATE
    1124 {
    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 stream
    1129      * 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 gone
    1132      *  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 = 0x7fffffff
    1144 } 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 PDMIHOSTAUDIO
    1154 {
    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 the
    1180      *                          previous).
    1181      * @param   pszId           The PDMAUDIOHOSTDEV::pszId value of the device to
    1182      *                          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 will
    1199      * 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 of
    1202      * failure/success on its own.
    1203      *
    1204      * This method is optional.  A non-NULL will, together with pfnStreamInitAsync
    1205      * 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 the
    1209      *                      PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.
    1210      * @param   uUser       User specific value as specified in the
    1211      *                      PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.
    1212      * @param   pvUser      User specific pointer as specified in the
    1213      *                      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 stream
    1222      * 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 blocked
    1225      * configuring host audio.
    1226      *
    1227      * The backend can return PDMAUDIOBACKEND_F_ASYNC_HINT in
    1228      * PDMIHOSTAUDIO::pfnGetConfig to avoid having EMT making this call and thereby
    1229      * speeding up VM construction.
    1230      *
    1231      * @param   pInterface      Pointer to this interface.
    1232      * @param   pCfg            The typical configuration.  (Feel free to change it
    1233      *                          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 its
    1242      * best match in the acquired configuration structure on success.
    1243      *
    1244      * @returns VBox status code.
    1245      * @retval  VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED if
    1246      *          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 is
    1251      *                          the same as @a *pCfgReq when called, the
    1252      *                          implementation will adjust it to make the actual
    1253      *                          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::pfnStreamCreate
    1262      * 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 continue
    1267      *                              initialization of.
    1268      * @param   fDestroyed          Set to @c true if the stream has been destroyed
    1269      *                              before the worker thread got to making this
    1270      *                              call.  The backend should just ready the stream
    1271      *                              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 draining
    1282      *                      stream (@c true), or to allow it to complete
    1283      *                      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 start
    1289      * 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 to
    1296      *                              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_ENABLE
    1308      */
    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_DISABLE
    1318      */
    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_PAUSE
    1328      */
    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_RESUME
    1338      */
    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 the
    1346      * backend with a way to drive it forwards.  These calls will come at a
    1347      * frequency set by the device and be on an asynchronous I/O thread.
    1348      *
    1349      * The PDMIHOSTAUDIO::pfnStreamDisable method maybe called if the device/mixer
    1350      * wants to re-enable the stream while it's still draining or if it gets
    1351      * impatient and thinks the draining has been going on too long, in which case
    1352      * the stream should stop immediately.
    1353      *
    1354      * @note    This should not wait for the stream to finish draining, just change
    1355      *          the state.  (The caller could be an EMT and it must not block for
    1356      *          hundreds of milliseconds of buffer to finish draining.)
    1357      *
    1358      * @note    Does not apply to input streams. Backends should refuse such
    1359      *          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_DRAIN
    1366      */
    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 after
    1405      * PDMAUDIOSTREAMCMD_DRAIN is issued when it's called every so often to assist
    1406      * the backend with moving the draining operation forward (kind of like
    1407      * 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 NULL
    1413      *                      when called to assist draining the stream.
    1414      * @param   cbBuf       The number of bytes of audio data to play.  This will be
    1415      *                      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 PDMIHOSTAUDIOPORT
    1456 {
    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 to
    1463      * complete, but returns immediately after submitting the request to the thread
    1464      * pool.
    1465      *
    1466      * @returns VBox status code.
    1467      * @param   pInterface  Pointer to this interface.
    1468      * @param   pStream     Optional backend stream structure to pass along.  The
    1469      *                      reference count will be increased till the call
    1470      *                      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 back
    1481      * (PDMIHOSTAUDIO::pfnStreamNotifyDeviceChanged) for all open streams in the
    1482      * given direction. (This ASSUMES the backend uses one output device and one
    1483      * 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 for
    1488      *                      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 when
    1496      * PDMIHOSTAUDIO::pfnStreamGetStatus is next called and change the stream state
    1497      * 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 the
    1507      * 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 audio
    1522      *       devices they are using.  This is mainly for triggering enumeration and
    1523      *       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 
    15351541RT_C_DECLS_END
    15361542
  • trunk/include/VBox/vmm/pdmaudioinline.h

    r89569 r89768  
    182182
    183183/*********************************************************************************************************************************
     184*  Volume Helpers                                                                                                                *
     185*********************************************************************************************************************************/
     186
     187/**
     188 * Initializes a PDMAUDIOVOLUME structure to max.
     189 *
     190 * @param   pVol    The structure to initialize.
     191 */
     192DECLINLINE(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 */
     210DECLINLINE(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 */
     229DECLINLINE(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/*********************************************************************************************************************************
    184262*   PCM Property Helpers                                                                                                         *
    185263*********************************************************************************************************************************/
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette