diff --git a/src/add-ons/kernel/drivers/audio/hda/device.cpp b/src/add-ons/kernel/drivers/audio/hda/device.cpp index f114f0ffc7..d0217bf393 100644 --- a/src/add-ons/kernel/drivers/audio/hda/device.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/device.cpp @@ -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; } diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.h b/src/add-ons/kernel/drivers/audio/hda/driver.h index 5d5421e6b2..7abef585a0 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.h +++ b/src/add-ons/kernel/drivers/audio/hda/driver.h @@ -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); diff --git a/src/add-ons/kernel/drivers/audio/hda/hda.settings b/src/add-ons/kernel/drivers/audio/hda/hda.settings new file mode 100644 index 0000000000..9f1b53a0fb --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/hda/hda.settings @@ -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 diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp index 100a13cd7a..a30f3cdca2 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp @@ -8,6 +8,8 @@ */ +#include + #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);