diff options
author | Misael Lopez Cruz <misael.lopez@ti.com> | 2013-12-10 02:48:39 -0600 |
---|---|---|
committer | Misael Lopez Cruz <misael.lopez@ti.com> | 2014-01-13 17:36:14 -0600 |
commit | e926655ecbaf438e054ba1f2452be3b9768efe51 (patch) | |
tree | 8279d32f6583388a35d0d740746ab466b70440fb | |
parent | 0e9b0a6d2cc67b7822dd625f60070cfe75b6558b (diff) | |
download | common-open-e926655ecbaf438e054ba1f2452be3b9768efe51.tar.gz |
audio: utils: Add PCM start and stop
PCM start and stop is mostly needed for hostless ports, since
they require to be explicitly started/stopped. PCM stop can also
be used to unblock read() or write() calls.
Change-Id: Ie651d90933022df754c582a89733d607101ea585
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
-rw-r--r-- | audio/utils/include/tiaudioutils/ALSAPcm.h | 50 | ||||
-rw-r--r-- | audio/utils/include/tiaudioutils/NullPcm.h | 40 | ||||
-rw-r--r-- | audio/utils/include/tiaudioutils/Pcm.h | 20 | ||||
-rw-r--r-- | audio/utils/src/ALSAPcm.cpp | 52 |
4 files changed, 162 insertions, 0 deletions
diff --git a/audio/utils/include/tiaudioutils/ALSAPcm.h b/audio/utils/include/tiaudioutils/ALSAPcm.h index 830e304..030db84 100644 --- a/audio/utils/include/tiaudioutils/ALSAPcm.h +++ b/audio/utils/include/tiaudioutils/ALSAPcm.h @@ -116,6 +116,31 @@ class ALSAInPort : public PcmInPort { */ int read(void *buffer, size_t frames); + /** + * \brief Start the ALSA PCM port + * + * Starts the ALSA PCM capture port. It's mostly needed to start hostless + * ports that don't use read() but instead run without CPU intervention. + * Regular PCM read through read() method doesn't need to be explicitly + * preceded by start(), since it's done internally. + * + * \return 0 on success, otherwise negative error code + */ + int start(); + + /** + * \brief Stop the ALSA PCM port + * + * Stops the ALSA PCM capture port. It's mostly needed to stop hostless + * ports that don't use read() but instead run without CPU intervention. + * Regular PCM read through read() method doesn't need to be explicitly + * stopped, but if done, it will cause read() to immediately return. + * This behavior can be desired to unblock read() calls. + * + * \return 0 on success, otherwise negative error code + */ + int stop(); + /** Default number of periods for the tinyalsa config of the capture port */ static const uint32_t kDefaultNumPeriods = 3; @@ -215,6 +240,31 @@ class ALSAOutPort : public PcmOutPort { */ int write(const void *buffer, size_t frames); + /** + * \brief Start the ALSA PCM port + * + * Starts the ALSA PCM playback port. It's mostly needed to start hostless + * ports that don't use write() but instead run without CPU intervention. + * Regular PCM write through write() method doesn't need to be explicitly + * preceded by start(), since it's done internally. + * + * \return 0 on success, otherwise negative error code + */ + int start(); + + /** + * \brief Stop the ALSA PCM port + * + * Stops the ALSA PCM playback port. It's mostly needed to stop hostless + * ports that don't use write() but instead run without CPU intervention. + * Regular PCM write through write() method doesn't need to be explicitly + * stopped, but if done, it will cause write() to immediately return. + * This behavior can be desired to unblock write() calls. + * + * \return 0 on success, otherwise negative error code + */ + int stop(); + /** Default number of periods for the tinyalsa config of the playback port */ static const uint32_t kDefaultNumPeriods = 4; diff --git a/audio/utils/include/tiaudioutils/NullPcm.h b/audio/utils/include/tiaudioutils/NullPcm.h index 8995759..977faaa 100644 --- a/audio/utils/include/tiaudioutils/NullPcm.h +++ b/audio/utils/include/tiaudioutils/NullPcm.h @@ -118,6 +118,26 @@ class NullInPort : public PcmInPort { */ int read(void *buffer, size_t frames); + /** + * \brief Start the null PCM port + * + * Starts the null PCM capture port. No meaningful action is performed + * by this method. + * + * \return 0 on success, otherwise negative error code + */ + int start() { return 0; } + + /** + * \brief Stop the null PCM port + * + * Stops the null PCM capture port. No meaningful action is performed + * by this method. + * + * \return 0 on success, otherwise negative error code + */ + int stop() { return 0; } + private: NullInPort(const NullInPort &port); NullInPort& operator=(const NullInPort &port); @@ -215,6 +235,26 @@ class NullOutPort : public PcmOutPort { */ int write(const void *buffer, size_t frames); + /** + * \brief Start the null PCM port + * + * Starts the null PCM playback port. No meaningful action is performed + * by this method. + * + * \return 0 on success, otherwise negative error code + */ + int start() { return 0; } + + /** + * \brief Stop the null PCM port + * + * Stops the null PCM playback port. No meaningful action is performed + * by this method. + * + * \return 0 on success, otherwise negative error code + */ + int stop() { return 0; } + private: NullOutPort(const NullOutPort &port); NullOutPort& operator=(const NullOutPort &port); diff --git a/audio/utils/include/tiaudioutils/Pcm.h b/audio/utils/include/tiaudioutils/Pcm.h index a086d36..7d3ecd8 100644 --- a/audio/utils/include/tiaudioutils/Pcm.h +++ b/audio/utils/include/tiaudioutils/Pcm.h @@ -312,6 +312,26 @@ class PcmPort { * \return true if port is open, false otherwise */ virtual bool isOpen() const = 0; + + /** + * \brief Start the PCM port + * + * Starts the PCM port. It's mostly needed to start hostless ports that + * run without CPU intervention. + * + * \return 0 on success, otherwise negative error code + */ + virtual int start() = 0; + + /** + * \brief Stop the PCM port + * + * Stops the PCM capture port. It's mostly needed to stop hostless that + * run without CPU intervention. + * + * \return 0 on success, otherwise negative error code + */ + virtual int stop() = 0; }; /** diff --git a/audio/utils/src/ALSAPcm.cpp b/audio/utils/src/ALSAPcm.cpp index 37d6833..cea2199 100644 --- a/audio/utils/src/ALSAPcm.cpp +++ b/audio/utils/src/ALSAPcm.cpp @@ -115,6 +115,32 @@ int ALSAInPort::read(void *buffer, size_t frames) return frames; } +int ALSAInPort::start() +{ + AutoMutex lock(mLock); + + if (!mPcm || !pcm_is_ready(mPcm)) { + ALOGE("ALSAInPort: port hw:%u,%u is closed, cannot start", mCardId, mPortId); + return -EAGAIN; + } + + return pcm_start(mPcm); +} + +int ALSAInPort::stop() +{ + /* + * mLock is not acquired here because stop() is mostly needed to break + * blocked reads which runs with mLock held + */ + if (!mPcm || !pcm_is_ready(mPcm)) { + ALOGE("ALSAInPort: port hw:%u,%u is closed, cannot stop", mCardId, mPortId); + return -EAGAIN; + } + + return pcm_stop(mPcm); +} + /* ---------------------------------------------------------------------------------------- */ ALSAOutPort::ALSAOutPort(uint32_t card, uint32_t port, uint32_t period_count) @@ -207,4 +233,30 @@ int ALSAOutPort::write(const void *buffer, size_t frames) return frames; } +int ALSAOutPort::start() +{ + AutoMutex lock(mLock); + + if (!mPcm || !pcm_is_ready(mPcm)) { + ALOGE("ALSAOutPort: port hw:%u,%u is closed, cannot start", mCardId, mPortId); + return -EAGAIN; + } + + return pcm_start(mPcm); +} + +int ALSAOutPort::stop() +{ + /* + * mLock is not acquired here because stop() is mostly needed to break + * blocked writes which runs with mLock held + */ + if (!mPcm || !pcm_is_ready(mPcm)) { + ALOGE("ALSAOutPort: port hw:%u,%u is closed, cannot stop", mCardId, mPortId); + return -EAGAIN; + } + + return pcm_stop(mPcm); +} + } /* namespace tiaudioutils */ |