summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Audio/AudioMixer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Audio/AudioMixer.h')
-rw-r--r--src/VBox/Devices/Audio/AudioMixer.h263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/VBox/Devices/Audio/AudioMixer.h b/src/VBox/Devices/Audio/AudioMixer.h
new file mode 100644
index 00000000..7f62d3c7
--- /dev/null
+++ b/src/VBox/Devices/Audio/AudioMixer.h
@@ -0,0 +1,263 @@
+/* $Id: AudioMixer.h $ */
+/** @file
+ * VBox audio - Mixing routines.
+ *
+ * The mixing routines are mainly used by the various audio device emulations
+ * to achieve proper multiplexing from/to attached devices LUNs.
+ */
+
+/*
+ * Copyright (C) 2014-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef VBOX_INCLUDED_SRC_Audio_AudioMixer_h
+#define VBOX_INCLUDED_SRC_Audio_AudioMixer_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+#include <iprt/critsect.h>
+
+#include <VBox/vmm/pdmaudioifs.h>
+
+/**
+ * Structure for maintaining an audio mixer instance.
+ */
+typedef struct AUDIOMIXER
+{
+ /** The mixer's name. */
+ char *pszName;
+ /** The mixer's critical section. */
+ RTCRITSECT CritSect;
+ /** The master volume of this mixer. */
+ PDMAUDIOVOLUME VolMaster;
+ /** List of audio mixer sinks. */
+ RTLISTANCHOR lstSinks;
+ /** Number of used audio sinks. */
+ uint8_t cSinks;
+} AUDIOMIXER, *PAUDIOMIXER;
+
+/** Defines an audio mixer stream's flags. */
+#define AUDMIXSTREAMFLAGS uint32_t
+
+/** No flags specified. */
+#define AUDMIXSTREAM_FLAG_NONE 0
+
+/** Prototype needed for AUDMIXSTREAM struct definition. */
+typedef struct AUDMIXSINK *PAUDMIXSINK;
+
+/**
+ * Structure for maintaining an audio mixer stream.
+ */
+typedef struct AUDMIXSTREAM
+{
+ /** List node. */
+ RTLISTNODE Node;
+ /** Name of this stream. */
+ char *pszName;
+ /** The streams's critical section. */
+ RTCRITSECT CritSect;
+ /** Sink this stream is attached to. */
+ PAUDMIXSINK pSink;
+ /** Stream flags of type AUDMIXSTREAM_FLAG_. */
+ uint32_t fFlags;
+ /** Pointer to audio connector being used. */
+ PPDMIAUDIOCONNECTOR pConn;
+ /** Pointer to PDM audio stream this mixer stream handles. */
+ PPDMAUDIOSTREAM pStream;
+ /** Last read (recording) / written (playback) timestamp (in ns). */
+ uint64_t tsLastReadWrittenNs;
+ /** The stream's circular buffer for temporarily
+ * holding (raw) device audio data. */
+ PRTCIRCBUF pCircBuf;
+} AUDMIXSTREAM, *PAUDMIXSTREAM;
+
+/** Defines an audio sink's current status. */
+#define AUDMIXSINKSTS uint32_t
+
+/** No status specified. */
+#define AUDMIXSINK_STS_NONE 0
+/** The sink is active and running. */
+#define AUDMIXSINK_STS_RUNNING RT_BIT(0)
+/** The sink is in a pending disable state. */
+#define AUDMIXSINK_STS_PENDING_DISABLE RT_BIT(1)
+/** Dirty flag.
+ * For output sinks this means that there is data in the
+ * sink which has not been played yet.
+ * For input sinks this means that there is data in the
+ * sink which has been recorded but not transferred to the
+ * destination yet. */
+#define AUDMIXSINK_STS_DIRTY RT_BIT(2)
+
+/**
+ * Audio mixer sink direction.
+ */
+typedef enum AUDMIXSINKDIR
+{
+ /** Unknown direction. */
+ AUDMIXSINKDIR_UNKNOWN = 0,
+ /** Input (capturing from a device). */
+ AUDMIXSINKDIR_INPUT,
+ /** Output (playing to a device). */
+ AUDMIXSINKDIR_OUTPUT,
+ /** The usual 32-bit hack. */
+ AUDMIXSINKDIR_32BIT_HACK = 0x7fffffff
+} AUDMIXSINKDIR;
+
+/**
+ * Audio mixer sink command.
+ */
+typedef enum AUDMIXSINKCMD
+{
+ /** Unknown command, do not use. */
+ AUDMIXSINKCMD_UNKNOWN = 0,
+ /** Enables the sink. */
+ AUDMIXSINKCMD_ENABLE,
+ /** Disables the sink. */
+ AUDMIXSINKCMD_DISABLE,
+ /** Pauses the sink. */
+ AUDMIXSINKCMD_PAUSE,
+ /** Resumes the sink. */
+ AUDMIXSINKCMD_RESUME,
+ /** Tells the sink's streams to drop all (buffered) data immediately. */
+ AUDMIXSINKCMD_DROP,
+ /** Hack to blow the type up to 32-bit. */
+ AUDMIXSINKCMD_32BIT_HACK = 0x7fffffff
+} AUDMIXSINKCMD;
+
+/**
+ * Structure for keeping audio input sink specifics.
+ * Do not use directly. Instead, use AUDMIXSINK.
+ */
+typedef struct AUDMIXSINKIN
+{
+ /** The current recording source. Can be NULL if not set. */
+ PAUDMIXSTREAM pStreamRecSource;
+} AUDMIXSINKIN;
+
+/**
+ * Structure for keeping audio output sink specifics.
+ * Do not use directly. Instead, use AUDMIXSINK.
+ */
+typedef struct AUDMIXSINKOUT
+{
+} AUDMIXSINKOUT;
+
+/**
+ * Structure for maintaining an audio mixer sink.
+ */
+typedef struct AUDMIXSINK
+{
+ RTLISTNODE Node;
+ /** Pointer to mixer object this sink is bound to. */
+ PAUDIOMIXER pParent;
+ /** Name of this sink. */
+ char *pszName;
+ /** The sink direction, that is,
+ * if this sink handles input or output. */
+ AUDMIXSINKDIR enmDir;
+ /** The sink's critical section. */
+ RTCRITSECT CritSect;
+ /** This sink's mixing buffer, acting as
+ * a parent buffer for all streams this sink owns. */
+ PDMAUDIOMIXBUF MixBuf;
+ /** Union for input/output specifics. */
+ union
+ {
+ AUDMIXSINKIN In;
+ AUDMIXSINKOUT Out;
+ };
+ /** Sink status of type AUDMIXSINK_STS_XXX. */
+ AUDMIXSINKSTS fStatus;
+ /** The sink's PCM format. */
+ PDMAUDIOPCMPROPS PCMProps;
+ /** Number of streams assigned. */
+ uint8_t cStreams;
+ /** List of assigned streams.
+ * Note: All streams have the same PCM properties, so the
+ * mixer does not do any conversion. */
+ /** @todo Use something faster -- vector maybe? */
+ RTLISTANCHOR lstStreams;
+ /** The volume of this sink. The volume always will
+ * be combined with the mixer's master volume. */
+ PDMAUDIOVOLUME Volume;
+ /** The volume of this sink, combined with the last set master volume. */
+ PDMAUDIOVOLUME VolumeCombined;
+ /** Timestamp since last update (in ms). */
+ uint64_t tsLastUpdatedMs;
+ /** Last read (recording) / written (playback) timestamp (in ns). */
+ uint64_t tsLastReadWrittenNs;
+#ifdef VBOX_AUDIO_MIXER_DEBUG
+ struct
+ {
+ PPDMAUDIOFILE pFile;
+ } Dbg;
+#endif
+} AUDMIXSINK, *PAUDMIXSINK;
+
+/**
+ * Audio mixer operation.
+ */
+typedef enum AUDMIXOP
+{
+ /** Invalid operation, do not use. */
+ AUDMIXOP_INVALID = 0,
+ /** Copy data from A to B, overwriting data in B. */
+ AUDMIXOP_COPY,
+ /** Blend data from A with (existing) data in B. */
+ AUDMIXOP_BLEND,
+ /** The usual 32-bit hack. */
+ AUDMIXOP_32BIT_HACK = 0x7fffffff
+} AUDMIXOP;
+
+/** No flags specified. */
+#define AUDMIXSTRMCTL_FLAG_NONE 0
+
+int AudioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer);
+int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink);
+void AudioMixerDestroy(PAUDIOMIXER pMixer);
+void AudioMixerInvalidate(PAUDIOMIXER pMixer);
+void AudioMixerRemoveSink(PAUDIOMIXER pMixer, PAUDMIXSINK pSink);
+int AudioMixerSetMasterVolume(PAUDIOMIXER pMixer, PPDMAUDIOVOLUME pVol);
+void AudioMixerDebug(PAUDIOMIXER pMixer, PCDBGFINFOHLP pHlp, const char *pszArgs);
+
+int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
+int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, AUDMIXSTREAMFLAGS fFlags, PAUDMIXSTREAM *ppStream);
+int AudioMixerSinkCtl(PAUDMIXSINK pSink, AUDMIXSINKCMD enmCmd);
+void AudioMixerSinkDestroy(PAUDMIXSINK pSink);
+uint32_t AudioMixerSinkGetReadable(PAUDMIXSINK pSink);
+uint32_t AudioMixerSinkGetWritable(PAUDMIXSINK pSink);
+AUDMIXSINKDIR AudioMixerSinkGetDir(PAUDMIXSINK pSink);
+const char *AudioMixerSinkGetName(const PAUDMIXSINK pSink);
+PAUDMIXSTREAM AudioMixerSinkGetRecordingSource(PAUDMIXSINK pSink);
+PAUDMIXSTREAM AudioMixerSinkGetStream(PAUDMIXSINK pSink, uint8_t uIndex);
+AUDMIXSINKSTS AudioMixerSinkGetStatus(PAUDMIXSINK pSink);
+uint8_t AudioMixerSinkGetStreamCount(PAUDMIXSINK pSink);
+bool AudioMixerSinkIsActive(PAUDMIXSINK pSink);
+int AudioMixerSinkRead(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
+void AudioMixerSinkRemoveStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
+void AudioMixerSinkRemoveAllStreams(PAUDMIXSINK pSink);
+void AudioMixerSinkReset(PAUDMIXSINK pSink);
+void AudioMixerSinkGetFormat(PAUDMIXSINK pSink, PPDMAUDIOPCMPROPS pPCMProps);
+int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PPDMAUDIOPCMPROPS pPCMProps);
+int AudioMixerSinkSetRecordingSource(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
+int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol);
+int AudioMixerSinkWrite(PAUDMIXSINK pSink, AUDMIXOP enmOp, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
+int AudioMixerSinkUpdate(PAUDMIXSINK pSink);
+
+int AudioMixerStreamCtl(PAUDMIXSTREAM pStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl);
+void AudioMixerStreamDestroy(PAUDMIXSTREAM pStream);
+bool AudioMixerStreamIsActive(PAUDMIXSTREAM pStream);
+bool AudioMixerStreamIsValid(PAUDMIXSTREAM pStream);
+
+#endif /* !VBOX_INCLUDED_SRC_Audio_AudioMixer_h */
+