Commit 7f34e941 authored by Max Kellermann's avatar Max Kellermann

pcm: added pcm_convert_deinit(), pcm_resample_deinit()

Free memory allocated by libsamplerate when the output or the decoder is closed.
parent 97b844ec
...@@ -45,8 +45,6 @@ void decoder_initialized(struct decoder * decoder, ...@@ -45,8 +45,6 @@ void decoder_initialized(struct decoder * decoder,
assert(audio_format_defined(audio_format)); assert(audio_format_defined(audio_format));
assert(audio_format_valid(audio_format)); assert(audio_format_valid(audio_format));
pcm_convert_init(&decoder->conv_state);
dc.in_audio_format = *audio_format; dc.in_audio_format = *audio_format;
getOutputAudioFormat(audio_format, &dc.out_audio_format); getOutputAudioFormat(audio_format, &dc.out_audio_format);
......
...@@ -124,6 +124,8 @@ static void decoder_run_song(const struct song *song, const char *uri) ...@@ -124,6 +124,8 @@ static void decoder_run_song(const struct song *song, const char *uri)
return; return;
} }
pcm_convert_init(&decoder.conv_state);
ret = false; ret = false;
if (!song_is_file(song)) { if (!song_is_file(song)) {
unsigned int next = 0; unsigned int next = 0;
...@@ -187,6 +189,8 @@ static void decoder_run_song(const struct song *song, const char *uri) ...@@ -187,6 +189,8 @@ static void decoder_run_song(const struct song *song, const char *uri)
} }
} }
pcm_convert_deinit(&decoder.conv_state);
music_pipe_flush(); music_pipe_flush();
if (close_instream) if (close_instream)
......
...@@ -84,6 +84,7 @@ static void ao_play(struct audio_output *ao) ...@@ -84,6 +84,7 @@ static void ao_play(struct audio_output *ao)
if (!ret) { if (!ret) {
ao->plugin->cancel(ao->data); ao->plugin->cancel(ao->data);
ao->plugin->close(ao->data); ao->plugin->close(ao->data);
pcm_convert_deinit(&ao->convState);
ao->open = false; ao->open = false;
} }
...@@ -118,6 +119,8 @@ static gpointer audio_output_task(gpointer arg) ...@@ -118,6 +119,8 @@ static gpointer audio_output_task(gpointer arg)
case AO_COMMAND_OPEN: case AO_COMMAND_OPEN:
assert(!ao->open); assert(!ao->open);
pcm_convert_init(&ao->convState);
ret = ao->plugin->open(ao->data, ret = ao->plugin->open(ao->data,
&ao->outAudioFormat); &ao->outAudioFormat);
...@@ -134,6 +137,7 @@ static gpointer audio_output_task(gpointer arg) ...@@ -134,6 +137,7 @@ static gpointer audio_output_task(gpointer arg)
assert(ao->open); assert(ao->open);
ao->plugin->cancel(ao->data); ao->plugin->cancel(ao->data);
ao->plugin->close(ao->data); ao->plugin->close(ao->data);
ao->open = false; ao->open = false;
ao_command_finished(ao); ao_command_finished(ao);
break; break;
......
...@@ -37,6 +37,11 @@ void pcm_convert_init(struct pcm_convert_state *state) ...@@ -37,6 +37,11 @@ void pcm_convert_init(struct pcm_convert_state *state)
pcm_dither_24_init(&state->dither); pcm_dither_24_init(&state->dither);
} }
void pcm_convert_deinit(struct pcm_convert_state *state)
{
pcm_resample_deinit(&state->resample);
}
static size_t static size_t
pcm_convert_16(const struct audio_format *src_format, pcm_convert_16(const struct audio_format *src_format,
const void *src_buffer, size_t src_size, const void *src_buffer, size_t src_size,
......
...@@ -32,6 +32,8 @@ struct pcm_convert_state { ...@@ -32,6 +32,8 @@ struct pcm_convert_state {
void pcm_convert_init(struct pcm_convert_state *state); void pcm_convert_init(struct pcm_convert_state *state);
void pcm_convert_deinit(struct pcm_convert_state *state);
size_t pcm_convert(const struct audio_format *inFormat, size_t pcm_convert(const struct audio_format *inFormat,
const void *src, size_t src_size, const void *src, size_t src_size,
const struct audio_format *outFormat, const struct audio_format *outFormat,
......
...@@ -52,6 +52,8 @@ struct pcm_resample_state { ...@@ -52,6 +52,8 @@ struct pcm_resample_state {
void pcm_resample_init(struct pcm_resample_state *state); void pcm_resample_init(struct pcm_resample_state *state);
void pcm_resample_deinit(struct pcm_resample_state *state);
size_t size_t
pcm_resample_16(uint8_t channels, pcm_resample_16(uint8_t channels,
unsigned src_rate, unsigned src_rate,
......
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
#include <assert.h> #include <assert.h>
#include <glib.h> #include <glib.h>
void pcm_resample_deinit(G_GNUC_UNUSED struct pcm_resample_state *state)
{
/* no state, nothing to do */
}
/* resampling code blatantly ripped from ESD */ /* resampling code blatantly ripped from ESD */
size_t size_t
pcm_resample_16(uint8_t channels, pcm_resample_16(uint8_t channels,
......
...@@ -29,6 +29,13 @@ ...@@ -29,6 +29,13 @@
#undef G_LOG_DOMAIN #undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "pcm" #define G_LOG_DOMAIN "pcm"
void pcm_resample_deinit(G_GNUC_UNUSED struct pcm_resample_state *state)
{
if (state->state != NULL)
state->state = src_delete(state->state);
}
static int pcm_resample_get_converter(void) static int pcm_resample_get_converter(void)
{ {
const char *conf = getConfigParamValue(CONF_SAMPLERATE_CONVERTER); const char *conf = getConfigParamValue(CONF_SAMPLERATE_CONVERTER);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment