summaryrefslogtreecommitdiff
path: root/audio/talsa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/talsa.cpp')
-rw-r--r--audio/talsa.cpp96
1 files changed, 60 insertions, 36 deletions
diff --git a/audio/talsa.cpp b/audio/talsa.cpp
index 4c2d7f84..c5d232dc 100644
--- a/audio/talsa.cpp
+++ b/audio/talsa.cpp
@@ -152,6 +152,10 @@ PcmPtr pcmOpen(const unsigned int dev,
pcm_config.period_size =
periodSettings.periodSizeMultiplier * frameCount / periodSettings.periodCount;
pcm_config.format = PCM_FORMAT_S16_LE;
+ if (isOut) {
+ pcm_config.start_threshold = pcm_config.period_size * (pcm_config.period_count - 1);
+ pcm_config.stop_threshold = pcm_config.period_size * pcm_config.period_count;
+ }
pcm_t *pcmRaw = ::pcm_open(dev, card,
(isOut ? PCM_OUT : PCM_IN) | PCM_MONOTONIC,
@@ -183,58 +187,78 @@ PcmPtr pcmOpen(const unsigned int dev,
return pcm;
}
-bool pcmRead(pcm_t *pcm, void *data, unsigned int count) {
+int pcmRead(pcm_t *pcm, void *data, const int szBytes,
+ const unsigned int frameSize) {
+ LOG_ALWAYS_FATAL_IF(frameSize == 0);
+ LOG_ALWAYS_FATAL_IF(szBytes < 0, "szBytes=%d", szBytes);
+ LOG_ALWAYS_FATAL_IF((szBytes % frameSize) != 0, "szBytes=%d frameSize=%u",
+ szBytes, frameSize);
if (!pcm) {
- return FAILURE(false);
+ return FAILURE(-1);
}
+ const int szFrames = szBytes / frameSize;
int tries = 3;
while (true) {
- --tries;
- const int r = ::pcm_read(pcm, data, count);
- switch (-r) {
- case 0:
- return true;
-
- case EIO:
- case EAGAIN:
- if (tries > 0) {
- break;
+ const int framesRead = ::pcm_readi(pcm, data, szFrames);
+ if (framesRead > 0) {
+ LOG_ALWAYS_FATAL_IF(framesRead > szFrames,
+ "framesRead=%d szFrames=%d szBytes=%u frameSize=%u",
+ framesRead, szFrames, szBytes, frameSize);
+ return framesRead * frameSize;
+ } else {
+ --tries;
+ switch (-framesRead) {
+ case EIO:
+ case EAGAIN:
+ if (tries > 0) {
+ break;
+ }
+ [[fallthrough]];
+
+ default:
+ ALOGW("%s:%d pcm_readi failed with '%s' (%d)",
+ __func__, __LINE__, ::pcm_get_error(pcm), framesRead);
+ return FAILURE(-1);
}
- [[fallthrough]];
-
- default:
- ALOGW("%s:%d pcm_read failed with '%s' (%d)",
- __func__, __LINE__, ::pcm_get_error(pcm), r);
- return FAILURE(false);
}
}
}
-bool pcmWrite(pcm_t *pcm, const void *data, unsigned int count) {
+int pcmWrite(pcm_t *pcm, const void *data, const int szBytes,
+ const unsigned int frameSize) {
+ LOG_ALWAYS_FATAL_IF(frameSize == 0);
+ LOG_ALWAYS_FATAL_IF(szBytes < 0, "szBytes=%d", szBytes);
+ LOG_ALWAYS_FATAL_IF((szBytes % frameSize) != 0, "szBytes=%d frameSize=%u",
+ szBytes, frameSize);
if (!pcm) {
- return FAILURE(false);
+ return FAILURE(-1);
}
+ const int szFrames = szBytes / frameSize;
int tries = 3;
while (true) {
- --tries;
- const int r = ::pcm_write(pcm, data, count);
- switch (-r) {
- case 0:
- return true;
-
- case EIO:
- case EAGAIN:
- if (tries > 0) {
- break;
+ const int framesWritten = ::pcm_writei(pcm, data, szFrames);
+ if (framesWritten > 0) {
+ LOG_ALWAYS_FATAL_IF(framesWritten > szFrames,
+ "framesWritten=%d szFrames=%d szBytes=%u frameSize=%u",
+ framesWritten, szFrames, szBytes, frameSize);
+ return framesWritten * frameSize;
+ } else {
+ --tries;
+ switch (-framesWritten) {
+ case EIO:
+ case EAGAIN:
+ if (tries > 0) {
+ break;
+ }
+ [[fallthrough]];
+
+ default:
+ ALOGW("%s:%d pcm_writei failed with '%s' (%d)",
+ __func__, __LINE__, ::pcm_get_error(pcm), framesWritten);
+ return FAILURE(-1);
}
- [[fallthrough]];
-
- default:
- ALOGW("%s:%d pcm_write failed with '%s' (%d)",
- __func__, __LINE__, ::pcm_get_error(pcm), r);
- return FAILURE(false);
}
}
}