From 8040a012b4602340db897fa86c4df968caca3b2b Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Sun, 12 Nov 2023 12:34:37 +0100 Subject: [PATCH] Driver for file-based audio input device --- meson.build | 1 + platform/drivers/audio/file_source.c | 120 +++++++++++++++++++++++++++ platform/drivers/audio/file_source.h | 43 ++++++++++ 3 files changed, 164 insertions(+) create mode 100644 platform/drivers/audio/file_source.c create mode 100644 platform/drivers/audio/file_source.h diff --git a/meson.build b/meson.build index b727ffeb..9ce86b02 100644 --- a/meson.build +++ b/meson.build @@ -285,6 +285,7 @@ linux_platform_src = ['platform/targets/linux/emulator/emulator.c', 'platform/mcu/x86_64/drivers/rng.cpp', 'platform/drivers/baseband/radio_linux.cpp', 'platform/drivers/audio/audio_linux.c', + 'platform/drivers/audio/file_source.c', 'platform/targets/linux/platform.c', 'platform/drivers/CPS/cps_io_libc.c'] diff --git a/platform/drivers/audio/file_source.c b/platform/drivers/audio/file_source.c new file mode 100644 index 00000000..c5ea0ac5 --- /dev/null +++ b/platform/drivers/audio/file_source.c @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include +#include "file_source.h" + +static int fileSource_start(const uint8_t instance, const void *config, struct streamCtx *ctx) +{ + (void) instance; + + if(ctx == NULL) + return -EINVAL; + + if(ctx->running != 0) + return -EBUSY; + + ctx->running = 1; + + FILE *fp = fopen(config, "rb"); + if(fp == NULL) + { + ctx->running = 0; + return -EINVAL; + } + + ctx->priv = fp; + + return 0; +} + +static int fileSource_data(struct streamCtx *ctx, stream_sample_t **buf) +{ + if(ctx->running == 0) + return -1; + + FILE *fp = (FILE *) ctx->priv; + stream_sample_t *dest = *buf; + size_t size = ctx->bufSize; + size_t i; + + if(ctx->bufMode == BUF_CIRC_DOUBLE) + size /= 2; + + // Read data from the file, rollover when end is reached + while (i < size) + { + size_t n = fread(dest + i, sizeof(stream_sample_t), size - i, fp); + if (n < (size - i)) + fseek(fp, 0, SEEK_SET); + + i += n; + } + + return size; +} + +static int fileSource_sync(struct streamCtx *ctx, uint8_t dirty) +{ + (void) dirty; + + size_t size = ctx->bufSize; + if(ctx->bufMode == BUF_CIRC_DOUBLE) + size /= 2; + + // Simulate the time needed to get a new chunck of data from an equivalent + // hardware peripheral. + uint32_t waitTime = (1000000 * size) / ctx->sampleRate; + usleep(waitTime); + + return 0; +} + +static void fileSource_stop(struct streamCtx *ctx) +{ + if(ctx->running == 0) + return; + + FILE *fp = (FILE *) ctx->priv; + fclose(fp); +} + +static void fileSource_halt(struct streamCtx *ctx) +{ + if(ctx->running == 0) + return; + + FILE *fp = (FILE *) ctx->priv; + fclose(fp); +} + +#pragma GCC diagnostic ignored "-Wpedantic" +const struct audioDriver file_source_audio_driver = +{ + .start = fileSource_start, + .data = fileSource_data, + .sync = fileSource_sync, + .stop = fileSource_stop, + .terminate = fileSource_halt +}; +#pragma GCC diagnostic pop diff --git a/platform/drivers/audio/file_source.h b/platform/drivers/audio/file_source.h new file mode 100644 index 00000000..e0ffaf10 --- /dev/null +++ b/platform/drivers/audio/file_source.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef FILE_SOURCE_H +#define FILE_SOURCE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Driver providing an audio input stream from a file. File format should be + * raw, 16 bit, little endian. The configuration parameter is the file name with + * the full path. + */ + +extern const struct audioDriver file_source_audio_driver; + + +#ifdef __cplusplus +} +#endif + +#endif /* STM32_DAC_H */