HDA driver: use optional settings file

Patch by Pete Goodeve, ticket #9134.
(Removed play_sample_rate and record_sample_rate as suggested in
patch review, adjusted hda.settings accordingly.)

Tune buffer size and buffer count with an optional settings file
/boot/home/config/settings/kernel/drivers/hda.settings. Same as
it's done for the auich driver.

Pete:
> I [...] request 4 buffers of 1024 frames, I get a nice 13-14ms latency.

Change-Id: I3c1c64375d22b525afb970d5e8379b22b8514438
Reviewed-on: https://review.haiku-os.org/521
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
Humdinger 2018-09-09 19:41:12 +02:00 committed by Jérôme Duval
parent 62a788f323
commit 8aea77d00f
4 changed files with 103 additions and 0 deletions

View File

@ -35,6 +35,10 @@ hda_open(const char* name, uint32 flags, void** cookie)
atomic_add(&controller->opened, 1);
*cookie = controller;
// optional user-settable buffer frames and count
get_settings_from_file();
return B_OK;
}

View File

@ -365,6 +365,7 @@ void hda_codec_delete(hda_codec* codec);
/* hda_multi_audio.c */
status_t multi_audio_control(void* cookie, uint32 op, void* arg, size_t length);
void get_settings_from_file();
/* hda_controller.c: Basic controller support */
status_t hda_hw_init(hda_controller* controller);

View File

@ -0,0 +1,24 @@
# Settings file for the HDA driver
#
# This file should be moved to the directory
# ~/config/settings/kernel/drivers/
# Uncomment and edit any of the setting lines you wish to set.
# The values shown are just the defaults.
# Don't uncomment any that you don't need to differ from the default.
# Remember that latency will probably be at least
# 2*buffer_frames/sample_rate
# For real time audio, a buffer of 1024 frames at 192000
# should be good (<15ms).
# You will need more buffers if they're small.
# e.g.:
# play_buffer_frames 1024
# play_buffer_count 4
###########################################################
# play_buffer_frames 10240
# play_buffer_count 2
# record_buffer_frames 10240
# record_buffer_count 2

View File

@ -8,6 +8,8 @@
*/
#include <driver_settings.h>
#include "hmulti_audio.h"
#include "driver.h"
@ -71,6 +73,66 @@ format2size(uint32 format)
}
#define HDA_SETTINGS "hda.settings"
static struct {
int32 play_buffer_frames;
int32 play_buffer_count;
int32 record_buffer_frames;
int32 record_buffer_count;
} requested_settings;
void
get_settings_from_file()
{
const char *item;
char *end;
uint32 value;
memset(&requested_settings, 0, sizeof(requested_settings));
dprintf("looking for settings file\n");
void *settings_handle = load_driver_settings(HDA_SETTINGS);
if (settings_handle == NULL)
return;
item = get_driver_parameter (settings_handle, "play_buffer_frames", NULL,
NULL);
if (item) {
value = strtoul (item, &end, 0);
if (*end == '\0')
requested_settings.play_buffer_frames = value;
}
item = get_driver_parameter (settings_handle, "play_buffer_count", NULL,
NULL);
if (item) {
value = strtoul (item, &end, 0);
if (*end == '\0')
requested_settings.play_buffer_count = value;
}
item = get_driver_parameter (settings_handle, "record_buffer_frames", NULL,
NULL);
if (item) {
value = strtoul (item, &end, 0);
if (*end == '\0')
requested_settings.record_buffer_frames = value;
}
item = get_driver_parameter (settings_handle, "record_buffer_count", NULL,
NULL);
if (item) {
value = strtoul (item, &end, 0);
if (*end == '\0')
requested_settings.record_buffer_count = value;
}
unload_driver_settings(settings_handle);
}
static status_t
get_description(hda_audio_group* audioGroup, multi_description* data)
{
@ -890,6 +952,18 @@ default_buffer_length_for_rate(uint32 rate)
static status_t
get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data)
{
if (requested_settings.play_buffer_frames != 0)
data->request_playback_buffer_size = requested_settings.play_buffer_frames;
if (requested_settings.play_buffer_count != 0)
data->request_playback_buffers = requested_settings.play_buffer_count;
if (requested_settings.record_buffer_frames != 0)
data->request_record_buffer_size = requested_settings.record_buffer_frames;
if (requested_settings.record_buffer_count != 0)
data->request_record_buffers = requested_settings.record_buffer_count;
TRACE("playback: %" B_PRId32 " buffers, %" B_PRId32 " channels, %" B_PRIu32
" samples\n", data->request_playback_buffers,
data->request_playback_channels, data->request_playback_buffer_size);