summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMisael Lopez Cruz <misael.lopez@ti.com>2013-12-10 02:48:39 -0600
committerMisael Lopez Cruz <misael.lopez@ti.com>2014-01-13 17:36:14 -0600
commite926655ecbaf438e054ba1f2452be3b9768efe51 (patch)
tree8279d32f6583388a35d0d740746ab466b70440fb
parent0e9b0a6d2cc67b7822dd625f60070cfe75b6558b (diff)
downloadcommon-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.h50
-rw-r--r--audio/utils/include/tiaudioutils/NullPcm.h40
-rw-r--r--audio/utils/include/tiaudioutils/Pcm.h20
-rw-r--r--audio/utils/src/ALSAPcm.cpp52
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 */