Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: audio drivers cleanup #5789

Merged
merged 6 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions radio/src/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#endif

#include "model_audio.h"
#include "hal/audio_driver.h"

extern RTOS_MUTEX_HANDLE audioMutex;

Expand Down Expand Up @@ -366,8 +367,6 @@ void audioTask(void * pdata)
RTOS_WAIT_TICKS(1);
}

setSampleRate(AUDIO_SAMPLE_RATE);

#if defined(PCBX12S) || defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
// The audio amp needs ~2s to start
RTOS_WAIT_MS(1000); // 1s
Expand All @@ -378,14 +377,21 @@ void audioTask(void * pdata)
DEBUG_TIMER_START(debugTimerAudioDuration);
audioQueue.wakeup();
DEBUG_TIMER_STOP(debugTimerAudioDuration);
RTOS_WAIT_MS(4);
RTOS_WAIT_MS(4); // ???
gagarinlg marked this conversation as resolved.
Show resolved Hide resolved
}
}
#endif

inline void mixSample(audio_data_t * result, int sample, unsigned int fade)
#if !defined(__SSAT)
#define _sat_s16(x) ((int16_t)limit<int32_t>(INT16_MIN, (x), INT16_MAX))
#else
#define _sat_s16(x) __SSAT((x), 16)
#endif

inline void mixSample(audio_data_t * result, int16_t sample, unsigned int fade)
{
*result = limit(AUDIO_DATA_MIN, *result + ((sample >> fade) >> (16-AUDIO_BITS_PER_SAMPLE)), AUDIO_DATA_MAX);
int32_t tmp = (int32_t)*result + ((int32_t)sample >> fade);
*result = (audio_data_t)_sat_s16(tmp);
}

#define RIFF_CHUNK_SIZE 12
Expand Down Expand Up @@ -646,15 +652,13 @@ void AudioQueue::wakeup()
buffer->data[i] = (int16_t) (((tmpSample * currentSpeakerVolume) / VOLUME_LEVEL_MAX) + AUDIO_DATA_SILENCE);
}
buffersFifo.audioPushBuffer();
}
else {
} else {
break;
}
#else
buffersFifo.audioPushBuffer();
#endif
}
else {
} else {
// break the endless loop
break;
}
Expand Down
151 changes: 33 additions & 118 deletions radio/src/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@

#include <stddef.h>
#include <string.h>

#include "ff.h"
#include "edgetx_types.h"
#include "dataconstants.h"

#include "hal/audio_driver.h"

/*
Implements a bit field, number of bits is set by the template,
each bit can be modified and read by the provided methods.
Expand Down Expand Up @@ -74,10 +77,17 @@ constexpr uint8_t AUDIO_FILENAME_MAXLEN = (AUDIO_LUA_FILENAME_MAXLEN > AUDIO_MOD

#define AUDIO_QUEUE_LENGTH (16) // must be a power of 2!

#define AUDIO_SAMPLE_RATE (32000)
#define AUDIO_BUFFER_DURATION (10)
#define AUDIO_BUFFER_SIZE (AUDIO_SAMPLE_RATE*AUDIO_BUFFER_DURATION/1000)

#if !defined(AUDIO_SAMPLE_FMT)
#if defined(SIMU) || defined(AUDIO_SPI)
#define AUDIO_SAMPLE_FMT AUDIO_SAMPLE_FMT_S16
#else
#define AUDIO_SAMPLE_FMT AUDIO_SAMPLE_FMT_U12
#endif
#endif

#if defined(SIMU) && defined(SIMU_AUDIO)
#define AUDIO_BUFFER_COUNT (10) // simulator needs more buffers for smooth audio
#elif defined(PCBX12S)
Expand All @@ -94,41 +104,19 @@ constexpr uint8_t AUDIO_FILENAME_MAXLEN = (AUDIO_LUA_FILENAME_MAXLEN > AUDIO_MOD

#define USE_SETTINGS_VOLUME (127)

#if defined(AUDIO_DUAL_BUFFER)
enum AudioBufferState
{
AUDIO_BUFFER_FREE,
AUDIO_BUFFER_FILLED,
AUDIO_BUFFER_PLAYING
};
#endif

#if defined(SIMU)
typedef uint16_t audio_data_t;
#define AUDIO_DATA_SILENCE 0x8000
#define AUDIO_DATA_MIN 0
#define AUDIO_DATA_MAX 0xffff
#define AUDIO_BITS_PER_SAMPLE 16
#elif defined(PCBX12S) || defined(PCBNV14)
#if AUDIO_SAMPLE_FMT == AUDIO_SAMPLE_FMT_S16
typedef int16_t audio_data_t;
#define AUDIO_DATA_SILENCE 0
#define AUDIO_DATA_MIN INT16_MIN
#define AUDIO_DATA_MAX INT16_MAX
#define AUDIO_BITS_PER_SAMPLE 16
#else
#define AUDIO_DATA_SILENCE 0
#elif AUDIO_SAMPLE_FMT == AUDIO_SAMPLE_FMT_U12
typedef uint16_t audio_data_t;
#define AUDIO_DATA_SILENCE (0x8000 >> 4)
#define AUDIO_DATA_MIN 0
#define AUDIO_DATA_MAX 0x0fff
#define AUDIO_BITS_PER_SAMPLE 12
#define AUDIO_DATA_SILENCE 0x8000
#else
#error "Unknown audio sample format"
#endif

struct AudioBuffer {
audio_data_t data[AUDIO_BUFFER_SIZE];
uint16_t size;
#if defined(AUDIO_DUAL_BUFFER)
uint8_t state;
#endif
};

extern AudioBuffer audioBuffers[AUDIO_BUFFER_COUNT];
Expand Down Expand Up @@ -314,115 +302,42 @@ class AudioBufferFifo {
private:
volatile uint8_t readIdx;
volatile uint8_t writeIdx;
volatile bool bufferFull;

// readIdx == writeIdx -> buffer empty
// readIdx == writeIdx + 1 -> buffer full

inline uint8_t nextBufferIdx(uint8_t idx) const
{
return (idx >= AUDIO_BUFFER_COUNT-1 ? 0 : idx+1);
}

bool full() const
{
return bufferFull;
}

bool empty() const
{
return (readIdx == writeIdx) && !bufferFull;
return (idx >= AUDIO_BUFFER_COUNT - 1 ? 0 : idx + 1);
}

uint8_t used() const
{
return bufferFull ? AUDIO_BUFFER_COUNT : writeIdx - readIdx;
}
bool full() const { return readIdx == nextBufferIdx(writeIdx); }
bool empty() const { return readIdx == writeIdx; }
uint8_t used() const { return (writeIdx - readIdx) % AUDIO_BUFFER_COUNT; }

public:
AudioBufferFifo() : readIdx(0), writeIdx(0), bufferFull(false)
public:
AudioBufferFifo() : readIdx(0), writeIdx(0)
{
memset(audioBuffers, 0, sizeof(audioBuffers));
}

// returns an empty buffer to be filled wit data and put back into FIFO with audioPushBuffer()
AudioBuffer * getEmptyBuffer() const
// returns an empty buffer to be filled with data and put back into FIFO
// with audioPushBuffer()
AudioBuffer *getEmptyBuffer() const
{
#if defined(AUDIO_DUAL_BUFFER)
AudioBuffer * buffer = &audioBuffers[writeIdx];
return buffer->state == AUDIO_BUFFER_FREE ? buffer : NULL;
#else
return full() ? NULL : &audioBuffers[writeIdx];
#endif
return full() ? nullptr : &audioBuffers[writeIdx];
}

// puts filled buffer into FIFO
void audioPushBuffer()
{
audioDisableIrq();
#if defined(AUDIO_DUAL_BUFFER)
AudioBuffer * buffer = &audioBuffers[writeIdx];
buffer->state = AUDIO_BUFFER_FILLED;
#endif
writeIdx = nextBufferIdx(writeIdx);
bufferFull = (writeIdx == readIdx);
audioEnableIrq();
}

// returns a pointer to the audio buffer to be played
const AudioBuffer * getNextFilledBuffer()
{
#if defined(AUDIO_DUAL_BUFFER)
uint8_t idx = readIdx;
do {
AudioBuffer * buffer = &audioBuffers[idx];
if (buffer->state == AUDIO_BUFFER_FILLED) {
buffer->state = AUDIO_BUFFER_PLAYING;
readIdx = idx;
return buffer;
}
idx = nextBufferIdx(idx);
} while (idx != writeIdx); // this fixes a bug if all buffers are filled
return NULL;
#else
return empty() ? NULL : &audioBuffers[readIdx];
#endif
}
void audioPushBuffer() { writeIdx = nextBufferIdx(writeIdx); }

// frees the last played buffer
void freeNextFilledBuffer()
{
audioDisableIrq();
#if defined(AUDIO_DUAL_BUFFER)
if (audioBuffers[readIdx].state == AUDIO_BUFFER_PLAYING) {
audioBuffers[readIdx].state = AUDIO_BUFFER_FREE;
readIdx = nextBufferIdx(readIdx);
bufferFull = false;
}
#else
readIdx = nextBufferIdx(readIdx);
bufferFull = false;
#endif
audioEnableIrq();
}
void freeNextFilledBuffer() { readIdx = nextBufferIdx(readIdx); }

bool filledAtleast(int noBuffers) const
// returns a pointer to the audio buffer to be played
const AudioBuffer *getNextFilledBuffer()
{
#if defined(AUDIO_DUAL_BUFFER)
int count = 0;
for(int n= 0; n<AUDIO_BUFFER_COUNT; ++n) {
if (audioBuffers[n].state == AUDIO_BUFFER_FILLED) {
if (++count >= noBuffers) {
return true;
}
}
}
return false;
#else
return used() >= noBuffers;
#endif
return empty() ? nullptr : &audioBuffers[readIdx];
}

bool filledAtleast(int noBuffers) const { return used() >= noBuffers; }
};

class AudioFragmentFifo
Expand Down
4 changes: 2 additions & 2 deletions radio/src/boards/generic_stm32/trainer_ports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#include "hal.h"

void board_trainer_init()
__WEAK void board_trainer_init()
{
#if defined(TRAINER_DETECT_GPIO)
gpio_init(TRAINER_DETECT_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
Expand Down Expand Up @@ -96,7 +96,7 @@ void trainer_init_dsc_in() {}
void trainer_stop_dsc() {}
#endif

bool is_trainer_dsc_connected()
__WEAK bool is_trainer_dsc_connected()
{
#if defined(TRAINER_DETECT_GPIO)
bool set = gpio_read(TRAINER_DETECT_GPIO);
Expand Down
17 changes: 9 additions & 8 deletions radio/src/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,22 @@
#include <FreeRTOS/include/FreeRTOS.h>
#include <FreeRTOS/include/stream_buffer.h>

#include "hal/adc_driver.h"
#include "hal/audio_driver.h"
#include "hal/fatfs_diskio.h"
#include "hal/module_port.h"
#include "hal/serial_driver.h"
#include "hal/storage.h"
#include "hal/usb_driver.h"
#include "hal/watchdog_driver.h"

#include "edgetx.h"
#include "timers_driver.h"
#include "hal/watchdog_driver.h"

#if defined(BLUETOOTH)
#include "bluetooth_driver.h"
#endif

#include "hal/adc_driver.h"
#include "hal/module_port.h"
#include "hal/fatfs_diskio.h"
#include "hal/storage.h"
#include "hal/usb_driver.h"

#include "tasks.h"
#include "tasks/mixer_task.h"

Expand Down Expand Up @@ -975,7 +976,7 @@ int cliSet(const char **argv)
else if (!strcmp(argv[1], "volume")) {
int level = 0;
if (toInt(argv, 2, &level) > 0) {
setVolume(level);
audioSetVolume(level);
} else {
cliSerialPrint("%s: Invalid argument \"%s\" \"%s\"", argv[0], argv[1],
argv[2]);
Expand Down
3 changes: 2 additions & 1 deletion radio/src/edgetx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "hal/watchdog_driver.h"
#include "hal/abnormal_reboot.h"
#include "hal/usb_driver.h"
#include "hal/audio_driver.h"

#include "timers_driver.h"

Expand Down Expand Up @@ -1465,7 +1466,7 @@ void edgeTxInit()
currentSpeakerVolume = requiredSpeakerVolume =
g_eeGeneral.speakerVolume + VOLUME_LEVEL_DEF;
#if !defined(SOFTWARE_VOLUME)
setScaledVolume(currentSpeakerVolume);
audioSetVolume(currentSpeakerVolume);
#endif
#endif

Expand Down
3 changes: 3 additions & 0 deletions radio/src/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

#include "edgetx.h"
#include "switches.h"

#include "hal/audio_driver.h"

#include "boards/generic_stm32/rgb_leds.h"

#if defined(COLORLCD)
Expand Down
1 change: 1 addition & 0 deletions radio/src/gui/128x64/radio_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "tasks/mixer_task.h"
#include "hal/adc_driver.h"
#include "hal/usb_driver.h"
#include "hal/audio_driver.h"
#include "input_mapping.h"

const unsigned char sticks[] = {
Expand Down
1 change: 1 addition & 0 deletions radio/src/gui/212x64/radio_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "hal/adc_driver.h"
#include "hal/usb_driver.h"
#include "hal/audio_driver.h"

#define LANGUAGE_PACKS_DEFINITION

Expand Down
2 changes: 2 additions & 0 deletions radio/src/gui/colorlcd/radio/radio_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

#include "hal/adc_driver.h"
#include "hal/usb_driver.h"
#include "hal/audio_driver.h"

#include "input_mapping.h"
#include "libopenui.h"
#include "edgetx.h"
Expand Down
Loading
Loading