Finite loop playing added

main
eleccoder 2022-12-23 09:45:58 +01:00
rodzic 698fa9aeda
commit 3d36dae2dc
2 zmienionych plików z 28 dodań i 11 usunięć

Wyświetl plik

@ -66,5 +66,8 @@ bool aprs_pico_sendAPRS(audio_buffer_pool_t* audio_buffer_pool,
* \param[in] freq_in_hz The frequency of the sine wave to be generated (in Hz) * \param[in] freq_in_hz The frequency of the sine wave to be generated (in Hz)
* \param[in] sample_freq_in_hz The sampling frequency of the sine wave to be generated (in Hz) * \param[in] sample_freq_in_hz The sampling frequency of the sine wave to be generated (in Hz)
* \param[in] volume The volume level of the generated signal (0 ... 256) * \param[in] volume The volume level of the generated signal (0 ... 256)
* \param[in] duration_in_ms For 'duration_in_ms' >= 0: Duration of the sine wave playing (in ms)
* For 'duration_in_ms' < 0: Plays the sine wave endlessly
*/ */
void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, unsigned int sample_freq_in_hz, uint16_t volume); void aprs_pico_play_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz,
unsigned int sample_freq_in_hz, uint16_t volume, int duration_in_ms);

Wyświetl plik

@ -106,18 +106,23 @@ static void aprs_pico_initClock(unsigned int sample_freq_in_hz)
* \param[in] pcm_data The PCM audio samples to be rendered * \param[in] pcm_data The PCM audio samples to be rendered
* \param[in] num_samples The number of PCM audio samples to be rendered * \param[in] num_samples The number of PCM audio samples to be rendered
* \param[in] volume The volume level of the generated AFSK signal (0 ... 256) * \param[in] volume The volume level of the generated AFSK signal (0 ... 256)
* \param[in] is_loop_forever If 'true', rendering of the audio samples will be continuously repeated * \param[in] num_loops For 'num_loops' >= 0 rendering of the audio samples will be repeated 'num_loops' times
* For 'num_loops' < 0, rendering of the audio samples will be endlessly repeated
*/ */
static void aprs_pico_renderAudioSamples(audio_buffer_pool_t* audio_buffer_pool, const int16_t* pcm_data, static void aprs_pico_renderAudioSamples(audio_buffer_pool_t* audio_buffer_pool, const int16_t* pcm_data,
unsigned int num_samples, uint16_t volume, bool is_loop_forever) unsigned int num_samples, uint16_t volume, int num_loops)
{ {
assert(audio_buffer_pool != NULL); assert(audio_buffer_pool != NULL);
assert(pcm_data != NULL); assert(pcm_data != NULL);
unsigned int idx_src = 0u; bool do_loop_forever = num_loops < 0;
bool is_all_samples_processed = num_samples == 0u; bool is_all_samples_processed = (num_samples == 0u) || (num_loops == 0);
unsigned int idx_src = 0u;
// Write the PCM sample data into the next audio buffer while applying the 'volume' value // Write the PCM sample data into the next audio buffer while applying the 'volume' value
// Loop over audio buffers
while (!is_all_samples_processed) while (!is_all_samples_processed)
{ {
audio_buffer_t* audio_buffer = take_audio_buffer(audio_buffer_pool, true); audio_buffer_t* audio_buffer = take_audio_buffer(audio_buffer_pool, true);
@ -125,6 +130,7 @@ static void aprs_pico_renderAudioSamples(audio_buffer_pool_t* audio_buffer_pool,
unsigned int idx_dst = 0u; unsigned int idx_dst = 0u;
// Fill the current audio buffer
while (!is_all_samples_processed && (idx_dst < audio_buffer->max_sample_count)) while (!is_all_samples_processed && (idx_dst < audio_buffer->max_sample_count))
{ {
audio_buffer_pcm_data[idx_dst] = ((int32_t)volume * (int32_t)pcm_data[idx_src]) >> 8u; audio_buffer_pcm_data[idx_dst] = ((int32_t)volume * (int32_t)pcm_data[idx_src]) >> 8u;
@ -134,13 +140,18 @@ static void aprs_pico_renderAudioSamples(audio_buffer_pool_t* audio_buffer_pool,
if (idx_src == num_samples) if (idx_src == num_samples)
{ {
if (is_loop_forever) if (!do_loop_forever)
{ {
idx_src = 0u; num_loops--;
}
if (num_loops == 0)
{
is_all_samples_processed = true;
} }
else else
{ {
is_all_samples_processed = true; idx_src = 0u;
} }
} }
} }
@ -169,7 +180,7 @@ static void aprs_pico_sendAPRSAudioCallback(const void* callback_user_data, cons
const AudioCallBackUserData_t user_data = *((AudioCallBackUserData_t*)callback_user_data); const AudioCallBackUserData_t user_data = *((AudioCallBackUserData_t*)callback_user_data);
aprs_pico_initClock(sample_freq_in_hz); aprs_pico_initClock(sample_freq_in_hz);
aprs_pico_renderAudioSamples(user_data.audio_buffer_pool, pcm_data, num_samples, user_data.volume, false); aprs_pico_renderAudioSamples(user_data.audio_buffer_pool, pcm_data, num_samples, user_data.volume, 1);
} }
@ -183,7 +194,8 @@ audio_buffer_pool_t* aprs_pico_init()
// See the header file for documentation // See the header file for documentation
void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, unsigned int sample_freq_in_hz, uint16_t volume) void aprs_pico_play_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz,
unsigned int sample_freq_in_hz, uint16_t volume, int duration_in_ms)
{ {
assert(audio_buffer_pool != NULL); assert(audio_buffer_pool != NULL);
@ -207,7 +219,9 @@ void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned i
sine_period_wave_table[i] = (wave_table_value_t)((float)WAVE_TABLE_VALUE_MAX * sinf(2.0f * (float)M_PI * (float)i / (float)num_samples_per_period)); sine_period_wave_table[i] = (wave_table_value_t)((float)WAVE_TABLE_VALUE_MAX * sinf(2.0f * (float)M_PI * (float)i / (float)num_samples_per_period));
} }
aprs_pico_renderAudioSamples(audio_buffer_pool, sine_period_wave_table, num_samples_per_period, volume, true); const int num_loops = duration_in_ms < 0 ? -1 : (duration_in_ms * (int)freq_in_hz / 1000);
aprs_pico_renderAudioSamples(audio_buffer_pool, sine_period_wave_table, num_samples_per_period, volume, num_loops);
free(sine_period_wave_table); free(sine_period_wave_table);
} }