Audio stream: fixed early start of input stream when in liner buffer mode

This commit is contained in:
Silvano Seva 2025-01-24 21:53:34 +01:00
parent 15a544e2ad
commit 23b16053df
1 changed files with 46 additions and 12 deletions

View File

@ -61,6 +61,27 @@ static bool validateStream(const streamId id)
return true; return true;
} }
/**
* \internal
* Start an audio stream. In case of failure, the stream is freed.
*
* @param id: stream ID.
* @return zero if the stream started, a negative error code otherwise.
*/
static int startStream(const streamId id)
{
const struct audioDevice *dev = streams[id].dev;
int ret = dev->driver->start(dev->instance, dev->config, &streams[id].ctx);
if(ret < 0)
{
streams[id].ctx.running = 0;
streams[id].path = 0;
}
return ret;
}
streamId audioStream_start(const pathId path, stream_sample_t * const buf, streamId audioStream_start(const pathId path, stream_sample_t * const buf,
const size_t length, const uint32_t sampleRate, const size_t length, const uint32_t sampleRate,
const uint8_t mode) const uint8_t mode)
@ -76,9 +97,11 @@ streamId audioStream_start(const pathId path, stream_sample_t * const buf,
// Search for an audio device serving the correct output endpoint. // Search for an audio device serving the correct output endpoint.
const struct audioDevice *dev = NULL; const struct audioDevice *dev = NULL;
const struct audioDevice *devs = inputDevices; const struct audioDevice *devs = inputDevices;
const uint8_t streamMode = (mode & 0xF0);
const uint8_t bufMode = (mode & 0x0F);
uint8_t endpoint = pathInfo.source; uint8_t endpoint = pathInfo.source;
if((mode & 0xF0) == STREAM_OUTPUT) if(streamMode == STREAM_OUTPUT)
{ {
devs = outputDevices; devs = outputDevices;
endpoint = pathInfo.sink; endpoint = pathInfo.sink;
@ -121,16 +144,16 @@ streamId audioStream_start(const pathId path, stream_sample_t * const buf,
streams[id].path = path; streams[id].path = path;
streams[id].dev = dev; streams[id].dev = dev;
streams[id].ctx.buffer = buf; streams[id].ctx.buffer = buf;
streams[id].ctx.bufMode = (mode & 0x0F); streams[id].ctx.bufMode = bufMode;
streams[id].ctx.bufSize = length; streams[id].ctx.bufSize = length;
streams[id].ctx.sampleRate = sampleRate; streams[id].ctx.sampleRate = sampleRate;
int ret = dev->driver->start(dev->instance, dev->config, &streams[id].ctx); // In circular mode, start immediately
if(ret < 0) if(bufMode == BUF_CIRC_DOUBLE)
{ {
streams[id].ctx.running = 0; int ret = startStream(id);
streams[id].path = 0; if(ret < 0)
return ret; return ret;
} }
return id; return id;
@ -163,18 +186,29 @@ void audioStream_terminate(const streamId id)
dataBlock_t inputStream_getData(streamId id) dataBlock_t inputStream_getData(streamId id)
{ {
dataBlock_t block; const struct audioDevice *dev = streams[id].dev;
block.data = NULL; dataBlock_t block = {NULL, 0};
block.len = 0; int ret;
if(validateStream(id) == false) if(validateStream(id) == false)
return block; return block;
int ret = streams[id].dev->driver->sync(&(streams[id].ctx), false); if(streams[id].ctx.bufMode == BUF_LINEAR)
{
ret = startStream(id);
if(ret < 0)
{
streams[id].ctx.running = 0;
streams[id].path = 0;
return block;
}
}
ret = dev->driver->sync(&(streams[id].ctx), false);
if(ret < 0) if(ret < 0)
return block; return block;
ret = streams[id].dev->driver->data(&(streams[id].ctx), &block.data); ret = dev->driver->data(&(streams[id].ctx), &block.data);
if(ret < 0) if(ret < 0)
{ {
block.data = NULL; block.data = NULL;