aboutsummaryrefslogtreecommitdiffstats
path: root/alsa-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'alsa-pcm.c')
-rw-r--r--alsa-pcm.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/alsa-pcm.c b/alsa-pcm.c
index ac9175b..d65809c 100644
--- a/alsa-pcm.c
+++ b/alsa-pcm.c
@@ -2,12 +2,13 @@
/*
* ALSA Virtual Soundcard
*
- * alsa-pcm.c - ALSA PCM implementation
+ * alsa-pcm.c - AVIRT ALSA PCM interface
*
* Copyright (C) 2010-2018 Fiberdyne Systems Pty Ltd
*/
-#include "alsa.h"
+#include "alsa-pcm.h"
+#include "utils.h"
#define DO_AUDIOPATH_CB(ap, callback, substream, ...) \
do { \
@@ -17,6 +18,36 @@
} \
} while (0)
+/**
+ * pcm_buff_complete_cb - PCM buffer complete callback
+ * @substreamid: pointer to ALSA PCM substream
+ * @return 0 on success or error code otherwise
+ *
+ * This should be called from a child Audio Path once it has finished processing
+ * the pcm buffer
+ */
+int pcm_buff_complete_cb(struct snd_pcm_substream *substream)
+{
+ // Notify ALSA middle layer of the elapsed period boundary
+ snd_pcm_period_elapsed(substream);
+
+ return 0;
+}
+
+static struct avirt_stream_group *avirt_stream_get_group(int direction)
+{
+ switch (direction) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ return &coreinfo.playback;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ return &coreinfo.capture;
+ default:
+ pr_err("[%s] Direction must be SNDRV_PCM_STREAM_XXX!",
+ __func__);
+ return NULL;
+ }
+}
+
/*******************************************************************************
* ALSA PCM Callbacks
******************************************************************************/
@@ -31,13 +62,12 @@
*/
static int pcm_open(struct snd_pcm_substream *substream)
{
- struct avirt_alsa_devconfig *config;
struct avirt_audiopath *audiopath;
- struct avirt_alsa_group *group;
+ struct avirt_stream_group *group;
struct snd_pcm_hardware *hw;
- unsigned int bytes_per_sample = 0, blocksize = 0;
+ unsigned int bytes_per_sample = 0, blocksize = 0, chans = 0;
- char *uid = "ap_dummy"; // TD MF: Make this dynamic!
+ char *uid = "ap_fddsp"; // TD MF: Make this dynamic!
audiopath = avirt_get_audiopath(uid);
CHK_NULL_V(audiopath, "Cannot find Audio Path uid: '%s'!", uid);
substream->private_data = audiopath;
@@ -58,7 +88,7 @@ static int pcm_open(struct snd_pcm_substream *substream)
}
// Get device group (playback/capture)
- group = avirt_alsa_get_group(substream->stream);
+ group = avirt_stream_get_group(substream->stream);
CHK_NULL(group);
// Check if substream id is valid
@@ -70,13 +100,13 @@ static int pcm_open(struct snd_pcm_substream *substream)
}
// Setup remaining hw properties
- config = &group->config[substream->pcm->device];
- hw->channels_min = config->channels;
- hw->channels_max = config->channels;
- hw->buffer_bytes_max = blocksize * hw->periods_max * bytes_per_sample *
- config->channels;
- hw->period_bytes_min = blocksize * bytes_per_sample * config->channels;
- hw->period_bytes_max = blocksize * bytes_per_sample * config->channels;
+ chans = group->streams[substream->pcm->device].channels;
+ hw->channels_min = chans;
+ hw->channels_max = chans;
+ hw->buffer_bytes_max =
+ blocksize * hw->periods_max * bytes_per_sample * chans;
+ hw->period_bytes_min = blocksize * bytes_per_sample * chans;
+ hw->period_bytes_max = blocksize * bytes_per_sample * chans;
// Do additional Audio Path 'open' callback
DO_AUDIOPATH_CB(audiopath, open, substream);
@@ -118,12 +148,12 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
int channels, err;
size_t bufsz;
struct avirt_audiopath *audiopath;
- struct avirt_alsa_group *group;
+ struct avirt_stream_group *group;
- group = avirt_alsa_get_group(substream->stream);
+ group = avirt_stream_get_group(substream->stream);
CHK_NULL(group);
- channels = group->config[substream->pcm->device].channels;
+ channels = group->streams[substream->pcm->device].channels;
if ((params_channels(hw_params) > channels) ||
(params_channels(hw_params) < channels)) {
@@ -252,11 +282,6 @@ static int pcm_get_time_info(
struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
{
- struct avirt_alsa_group *group;
-
- group = avirt_alsa_get_group(substream->stream);
- CHK_NULL(group);
-
DO_AUDIOPATH_CB(((struct avirt_audiopath *)substream->private_data),
get_time_info, substream, system_ts, audio_ts,
audio_tstamp_config, audio_tstamp_report);