[PATCH v8 5/6] audio: Add functions to initialize buffers

Akihiko Odaki posted 6 patches 1 month, 1 week ago
Maintainers: Gerd Hoffmann <kraxel@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Christian Schoenebeck <qemu_oss@crudebyte.com>, Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
[PATCH v8 5/6] audio: Add functions to initialize buffers
Posted by Akihiko Odaki 1 month, 1 week ago
These functions can be used to re-initialize buffers when hardware
parameters change due to device hotplug, for example.

Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
---
 audio/audio_int.h       |  2 ++
 audio/audio-mixeng-be.c | 24 ++++++++++++++++++------
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/audio/audio_int.h b/audio/audio_int.h
index 06f79ade6b0a..290cf373b49f 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -141,9 +141,11 @@ static inline void *advance(void *p, size_t incr)
 int wav_start_capture(AudioBackend *state, CaptureState *s, const char *path,
                       int freq, int bits, int nchannels);
 
+void audio_generic_initialize_buffer_in(HWVoiceIn *hw);
 void audio_generic_run_buffer_in(HWVoiceIn *hw);
 void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
 void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
+void audio_generic_initialize_buffer_out(HWVoiceOut *hw);
 void audio_generic_run_buffer_out(HWVoiceOut *hw);
 size_t audio_generic_buffer_get_free(HWVoiceOut *hw);
 void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
diff --git a/audio/audio-mixeng-be.c b/audio/audio-mixeng-be.c
index 370404505111..1419e7521503 100644
--- a/audio/audio-mixeng-be.c
+++ b/audio/audio-mixeng-be.c
@@ -1187,14 +1187,20 @@ void audio_run(AudioMixengBackend *s, const char *msg)
     }
 }
 
+void audio_generic_initialize_buffer_in(HWVoiceIn *hw)
+{
+    g_free(hw->buf_emul);
+    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
+    hw->buf_emul = g_malloc(hw->size_emul);
+    hw->pos_emul = hw->pending_emul = 0;
+}
+
 void audio_generic_run_buffer_in(HWVoiceIn *hw)
 {
     AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
 
     if (unlikely(!hw->buf_emul)) {
-        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
-        hw->buf_emul = g_malloc(hw->size_emul);
-        hw->pos_emul = hw->pending_emul = 0;
+        audio_generic_initialize_buffer_in(hw);
     }
 
     while (hw->pending_emul < hw->size_emul) {
@@ -1227,6 +1233,14 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
     hw->pending_emul -= size;
 }
 
+void audio_generic_initialize_buffer_out(HWVoiceOut *hw)
+{
+    g_free(hw->buf_emul);
+    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
+    hw->buf_emul = g_malloc(hw->size_emul);
+    hw->pos_emul = hw->pending_emul = 0;
+}
+
 size_t audio_generic_buffer_get_free(HWVoiceOut *hw)
 {
     if (hw->buf_emul) {
@@ -1260,9 +1274,7 @@ void audio_generic_run_buffer_out(HWVoiceOut *hw)
 void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
 {
     if (unlikely(!hw->buf_emul)) {
-        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
-        hw->buf_emul = g_malloc(hw->size_emul);
-        hw->pos_emul = hw->pending_emul = 0;
+        audio_generic_initialize_buffer_out(hw);
     }
 
     *size = MIN(hw->size_emul - hw->pending_emul,

-- 
2.53.0
Re: [PATCH v8 5/6] audio: Add functions to initialize buffers
Posted by Christian Schoenebeck 1 month, 1 week ago
On Wednesday, 4 March 2026 07:16:58 CET Akihiko Odaki wrote:
> These functions can be used to re-initialize buffers when hardware
> parameters change due to device hotplug, for example.
> 
> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
> Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
> ---
>  audio/audio_int.h       |  2 ++
>  audio/audio-mixeng-be.c | 24 ++++++++++++++++++------
>  2 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/audio/audio_int.h b/audio/audio_int.h
> index 06f79ade6b0a..290cf373b49f 100644
> --- a/audio/audio_int.h
> +++ b/audio/audio_int.h
> @@ -141,9 +141,11 @@ static inline void *advance(void *p, size_t incr)
>  int wav_start_capture(AudioBackend *state, CaptureState *s, const char
> *path, int freq, int bits, int nchannels);
> 
> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw);
>  void audio_generic_run_buffer_in(HWVoiceIn *hw);
>  void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
>  void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
> +void audio_generic_initialize_buffer_out(HWVoiceOut *hw);
>  void audio_generic_run_buffer_out(HWVoiceOut *hw);
>  size_t audio_generic_buffer_get_free(HWVoiceOut *hw);
>  void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
> diff --git a/audio/audio-mixeng-be.c b/audio/audio-mixeng-be.c
> index 370404505111..1419e7521503 100644
> --- a/audio/audio-mixeng-be.c
> +++ b/audio/audio-mixeng-be.c
> @@ -1187,14 +1187,20 @@ void audio_run(AudioMixengBackend *s, const char
> *msg) }
>  }
> 
> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw)
> +{
> +    g_free(hw->buf_emul);
> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> +    hw->buf_emul = g_malloc(hw->size_emul);
> +    hw->pos_emul = hw->pending_emul = 0;
> +}
> +
>  void audio_generic_run_buffer_in(HWVoiceIn *hw)
>  {
>      AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
> 
>      if (unlikely(!hw->buf_emul)) {
> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> -        hw->buf_emul = g_malloc(hw->size_emul);
> -        hw->pos_emul = hw->pending_emul = 0;
> +        audio_generic_initialize_buffer_in(hw);
>      }

It would be cleaner having split this patch over 2 patches. One for pure
refactoring (no behaviour change), and one that adds g_free(hw->buf_emul);

>      while (hw->pending_emul < hw->size_emul) {
> @@ -1227,6 +1233,14 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void
> *buf, size_t size) hw->pending_emul -= size;
>  }
> 
> +void audio_generic_initialize_buffer_out(HWVoiceOut *hw)
> +{
> +    g_free(hw->buf_emul);
> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> +    hw->buf_emul = g_malloc(hw->size_emul);
> +    hw->pos_emul = hw->pending_emul = 0;
> +}
> +
>  size_t audio_generic_buffer_get_free(HWVoiceOut *hw)
>  {
>      if (hw->buf_emul) {
> @@ -1260,9 +1274,7 @@ void audio_generic_run_buffer_out(HWVoiceOut *hw)
>  void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
>  {
>      if (unlikely(!hw->buf_emul)) {
> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> -        hw->buf_emul = g_malloc(hw->size_emul);
> -        hw->pos_emul = hw->pending_emul = 0;
> +        audio_generic_initialize_buffer_out(hw);
>      }
> 
>      *size = MIN(hw->size_emul - hw->pending_emul,
Re: [PATCH v8 5/6] audio: Add functions to initialize buffers
Posted by Akihiko Odaki 1 month, 1 week ago
On 2026/03/04 17:36, Christian Schoenebeck wrote:
> On Wednesday, 4 March 2026 07:16:58 CET Akihiko Odaki wrote:
>> These functions can be used to re-initialize buffers when hardware
>> parameters change due to device hotplug, for example.
>>
>> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>> Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
>> Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
>> ---
>>   audio/audio_int.h       |  2 ++
>>   audio/audio-mixeng-be.c | 24 ++++++++++++++++++------
>>   2 files changed, 20 insertions(+), 6 deletions(-)
>>
>> diff --git a/audio/audio_int.h b/audio/audio_int.h
>> index 06f79ade6b0a..290cf373b49f 100644
>> --- a/audio/audio_int.h
>> +++ b/audio/audio_int.h
>> @@ -141,9 +141,11 @@ static inline void *advance(void *p, size_t incr)
>>   int wav_start_capture(AudioBackend *state, CaptureState *s, const char
>> *path, int freq, int bits, int nchannels);
>>
>> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw);
>>   void audio_generic_run_buffer_in(HWVoiceIn *hw);
>>   void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
>>   void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
>> +void audio_generic_initialize_buffer_out(HWVoiceOut *hw);
>>   void audio_generic_run_buffer_out(HWVoiceOut *hw);
>>   size_t audio_generic_buffer_get_free(HWVoiceOut *hw);
>>   void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
>> diff --git a/audio/audio-mixeng-be.c b/audio/audio-mixeng-be.c
>> index 370404505111..1419e7521503 100644
>> --- a/audio/audio-mixeng-be.c
>> +++ b/audio/audio-mixeng-be.c
>> @@ -1187,14 +1187,20 @@ void audio_run(AudioMixengBackend *s, const char
>> *msg) }
>>   }
>>
>> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw)
>> +{
>> +    g_free(hw->buf_emul);
>> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
>> +    hw->buf_emul = g_malloc(hw->size_emul);
>> +    hw->pos_emul = hw->pending_emul = 0;
>> +}
>> +
>>   void audio_generic_run_buffer_in(HWVoiceIn *hw)
>>   {
>>       AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
>>
>>       if (unlikely(!hw->buf_emul)) {
>> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
>> -        hw->buf_emul = g_malloc(hw->size_emul);
>> -        hw->pos_emul = hw->pending_emul = 0;
>> +        audio_generic_initialize_buffer_in(hw);
>>       }
> 
> It would be cleaner having split this patch over 2 patches. One for pure
> refactoring (no behaviour change), and one that adds g_free(hw->buf_emul);

g_free() was added because the extracted function can be called with 
hw->buf_emul set. Extracting this into a function without adding 
g_free() makes the function dangerous with non-NULL hw->buf_emul. Adding 
g_free() without extracting it into a function doesn't make sense as it 
checks !hw->buf_emul immediate above.

Regards,
Akihiko Odaki

> 
>>       while (hw->pending_emul < hw->size_emul) {
>> @@ -1227,6 +1233,14 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void
>> *buf, size_t size) hw->pending_emul -= size;
>>   }
>>
>> +void audio_generic_initialize_buffer_out(HWVoiceOut *hw)
>> +{
>> +    g_free(hw->buf_emul);
>> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
>> +    hw->buf_emul = g_malloc(hw->size_emul);
>> +    hw->pos_emul = hw->pending_emul = 0;
>> +}
>> +
>>   size_t audio_generic_buffer_get_free(HWVoiceOut *hw)
>>   {
>>       if (hw->buf_emul) {
>> @@ -1260,9 +1274,7 @@ void audio_generic_run_buffer_out(HWVoiceOut *hw)
>>   void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
>>   {
>>       if (unlikely(!hw->buf_emul)) {
>> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
>> -        hw->buf_emul = g_malloc(hw->size_emul);
>> -        hw->pos_emul = hw->pending_emul = 0;
>> +        audio_generic_initialize_buffer_out(hw);
>>       }
>>
>>       *size = MIN(hw->size_emul - hw->pending_emul,
> 
> 
> 
>
Re: [PATCH v8 5/6] audio: Add functions to initialize buffers
Posted by Christian Schoenebeck 1 month, 1 week ago
On Wednesday, 4 March 2026 11:47:01 CET Akihiko Odaki wrote:
> On 2026/03/04 17:36, Christian Schoenebeck wrote:
> > On Wednesday, 4 March 2026 07:16:58 CET Akihiko Odaki wrote:
> >> These functions can be used to re-initialize buffers when hardware
> >> parameters change due to device hotplug, for example.
> >> 
> >> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> >> Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
> >> Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
> >> ---
[...]
> >> 
> >> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw)
> >> +{
> >> +    g_free(hw->buf_emul);
> >> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> >> +    hw->buf_emul = g_malloc(hw->size_emul);
> >> +    hw->pos_emul = hw->pending_emul = 0;
> >> +}
> >> +
> >> 
> >>   void audio_generic_run_buffer_in(HWVoiceIn *hw)
> >>   {
> >>   
> >>       AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
> >>       
> >>       if (unlikely(!hw->buf_emul)) {
> >> 
> >> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> >> -        hw->buf_emul = g_malloc(hw->size_emul);
> >> -        hw->pos_emul = hw->pending_emul = 0;
> >> +        audio_generic_initialize_buffer_in(hw);
> >> 
> >>       }
> > 
> > It would be cleaner having split this patch over 2 patches. One for pure
> > refactoring (no behaviour change), and one that adds g_free(hw->buf_emul);
> 
> g_free() was added because the extracted function can be called with
> hw->buf_emul set. Extracting this into a function without adding
> g_free() makes the function dangerous with non-NULL hw->buf_emul. Adding
> g_free() without extracting it into a function doesn't make sense as it
> checks !hw->buf_emul immediate above.

You are adding the function. So at this point, nobody could have called the
function by accident except you. And as you would have added g_malloc()
immediately with the next patch, there would be no danger.

In general it does make sense splitting pure refactoring from behaviour
changes. And by adding g_free() you are changing existing behaviour. That's
not bike shedding, it's for the sake of being able to skip all those white
noise changes when investigating if something breaks.

And the potential danger argument contradicts itself, because if the function
was called with an uninitialized structure then g_free() would crash. Without
g_free() it was just a potential memory leak OTOH. Choose your poison.

/Christian
Re: [PATCH v8 5/6] audio: Add functions to initialize buffers
Posted by Akihiko Odaki 1 month ago
On 2026/03/04 20:17, Christian Schoenebeck wrote:
> On Wednesday, 4 March 2026 11:47:01 CET Akihiko Odaki wrote:
>> On 2026/03/04 17:36, Christian Schoenebeck wrote:
>>> On Wednesday, 4 March 2026 07:16:58 CET Akihiko Odaki wrote:
>>>> These functions can be used to re-initialize buffers when hardware
>>>> parameters change due to device hotplug, for example.
>>>>
>>>> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>>>> Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
>>>> Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
>>>> ---
> [...]
>>>>
>>>> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw)
>>>> +{
>>>> +    g_free(hw->buf_emul);
>>>> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
>>>> +    hw->buf_emul = g_malloc(hw->size_emul);
>>>> +    hw->pos_emul = hw->pending_emul = 0;
>>>> +}
>>>> +
>>>>
>>>>    void audio_generic_run_buffer_in(HWVoiceIn *hw)
>>>>    {
>>>>    
>>>>        AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
>>>>        
>>>>        if (unlikely(!hw->buf_emul)) {
>>>>
>>>> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
>>>> -        hw->buf_emul = g_malloc(hw->size_emul);
>>>> -        hw->pos_emul = hw->pending_emul = 0;
>>>> +        audio_generic_initialize_buffer_in(hw);
>>>>
>>>>        }
>>>
>>> It would be cleaner having split this patch over 2 patches. One for pure
>>> refactoring (no behaviour change), and one that adds g_free(hw->buf_emul);
>>
>> g_free() was added because the extracted function can be called with
>> hw->buf_emul set. Extracting this into a function without adding
>> g_free() makes the function dangerous with non-NULL hw->buf_emul. Adding
>> g_free() without extracting it into a function doesn't make sense as it
>> checks !hw->buf_emul immediate above.
> 
> You are adding the function. So at this point, nobody could have called the
> function by accident except you. And as you would have added g_malloc()
> immediately with the next patch, there would be no danger.
> 
> In general it does make sense splitting pure refactoring from behaviour
> changes. And by adding g_free() you are changing existing behaviour. That's
> not bike shedding, it's for the sake of being able to skip all those white
> noise changes when investigating if something breaks.

You will also certainly wonder why adding g_free() in that case.

> 
> And the potential danger argument contradicts itself, because if the function
> was called with an uninitialized structure then g_free() would crash. Without
> g_free() it was just a potential memory leak OTOH. Choose your poison.

In the state machine of AudioMixengBackend it is NULL or a valid 
pointer: it never has an invalid pointer.

Marc-André Lureau, I'd like to ask you for an opinion on these matters 
since you are recently working on this and I think you are eventually 
going to make a pull request for this series.

Regards,
Akihiko Odaki

Re: [PATCH v8 5/6] audio: Add functions to initialize buffers
Posted by Marc-André Lureau 1 month, 1 week ago
On Wed, Mar 4, 2026 at 7:17 AM Akihiko Odaki
<odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>
> These functions can be used to re-initialize buffers when hardware
> parameters change due to device hotplug, for example.
>
> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
> Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

> ---
>  audio/audio_int.h       |  2 ++
>  audio/audio-mixeng-be.c | 24 ++++++++++++++++++------
>  2 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/audio/audio_int.h b/audio/audio_int.h
> index 06f79ade6b0a..290cf373b49f 100644
> --- a/audio/audio_int.h
> +++ b/audio/audio_int.h
> @@ -141,9 +141,11 @@ static inline void *advance(void *p, size_t incr)
>  int wav_start_capture(AudioBackend *state, CaptureState *s, const char *path,
>                        int freq, int bits, int nchannels);
>
> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw);
>  void audio_generic_run_buffer_in(HWVoiceIn *hw);
>  void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
>  void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
> +void audio_generic_initialize_buffer_out(HWVoiceOut *hw);
>  void audio_generic_run_buffer_out(HWVoiceOut *hw);
>  size_t audio_generic_buffer_get_free(HWVoiceOut *hw);
>  void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
> diff --git a/audio/audio-mixeng-be.c b/audio/audio-mixeng-be.c
> index 370404505111..1419e7521503 100644
> --- a/audio/audio-mixeng-be.c
> +++ b/audio/audio-mixeng-be.c
> @@ -1187,14 +1187,20 @@ void audio_run(AudioMixengBackend *s, const char *msg)
>      }
>  }
>
> +void audio_generic_initialize_buffer_in(HWVoiceIn *hw)
> +{
> +    g_free(hw->buf_emul);
> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> +    hw->buf_emul = g_malloc(hw->size_emul);
> +    hw->pos_emul = hw->pending_emul = 0;
> +}
> +
>  void audio_generic_run_buffer_in(HWVoiceIn *hw)
>  {
>      AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_GET_CLASS(hw->s);
>
>      if (unlikely(!hw->buf_emul)) {
> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> -        hw->buf_emul = g_malloc(hw->size_emul);
> -        hw->pos_emul = hw->pending_emul = 0;
> +        audio_generic_initialize_buffer_in(hw);
>      }
>
>      while (hw->pending_emul < hw->size_emul) {
> @@ -1227,6 +1233,14 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
>      hw->pending_emul -= size;
>  }
>
> +void audio_generic_initialize_buffer_out(HWVoiceOut *hw)
> +{
> +    g_free(hw->buf_emul);
> +    hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> +    hw->buf_emul = g_malloc(hw->size_emul);
> +    hw->pos_emul = hw->pending_emul = 0;
> +}
> +
>  size_t audio_generic_buffer_get_free(HWVoiceOut *hw)
>  {
>      if (hw->buf_emul) {
> @@ -1260,9 +1274,7 @@ void audio_generic_run_buffer_out(HWVoiceOut *hw)
>  void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size)
>  {
>      if (unlikely(!hw->buf_emul)) {
> -        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
> -        hw->buf_emul = g_malloc(hw->size_emul);
> -        hw->pos_emul = hw->pending_emul = 0;
> +        audio_generic_initialize_buffer_out(hw);
>      }
>
>      *size = MIN(hw->size_emul - hw->pending_emul,
>
> --
> 2.53.0
>