From 782ebbdf93e1a6fa13230efa01cbed373b41eebc Mon Sep 17 00:00:00 2001 From: Dario Casalinuovo Date: Mon, 12 Oct 2015 01:10:05 +0200 Subject: [PATCH] Cortex: Check retrieved timesource, fixes #11391 --- .../kernel/drivers/audio/hda/device.cpp | 3 + src/add-ons/kernel/drivers/audio/hda/driver.h | 1 + .../drivers/audio/hda/hda_multi_audio.cpp | 117 ++++++++++++++++++ .../cortex/RouteApp/RouteAppNodeManager.cpp | 2 + 4 files changed, 123 insertions(+) diff --git a/src/add-ons/kernel/drivers/audio/hda/device.cpp b/src/add-ons/kernel/drivers/audio/hda/device.cpp index f114f0ffc7..30594980ec 100644 --- a/src/add-ons/kernel/drivers/audio/hda/device.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/device.cpp @@ -35,6 +35,9 @@ hda_open(const char* name, uint32 flags, void** cookie) atomic_add(&controller->opened, 1); *cookie = controller; + + get_settings_from_file(); // optional user-settable sample rate, buffer frames and count + 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 c550ca8b7f..d2d17f2cb8 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.h +++ b/src/add-ons/kernel/drivers/audio/hda/driver.h @@ -375,6 +375,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_multi_audio.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp index eb7e358b7f..40e0a42336 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" @@ -69,6 +71,103 @@ format2size(uint32 format) } +#define HDA_SETTINGS "hda.settings" + +static struct { + int32 play_sample_rate; + int32 play_buffer_frames; + int32 play_buffer_count; + int32 record_sample_rate; + int32 record_buffer_frames; + int32 record_buffer_count; +} requested_settings; + + +static uint32 +fps_to_ratecode(uint32 fps) +{ + switch (fps) { + case 8000: + return B_SR_8000; + case 11025: + return B_SR_11025; + case 16000: + return B_SR_16000; + case 22050: + return B_SR_22050; + case 32000: + return B_SR_32000; + case 44100: + return B_SR_44100; + case 48000: + return B_SR_48000; + case 88200: + return B_SR_88200; + case 96000: + return B_SR_96000; + case 176400: + return B_SR_176400; + case 192000: + return B_SR_192000; + case 384000: + return B_SR_384000; + } + return 0; +} + + +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_sample_rate", "0", "192000"); + if (item) { + value = strtoul (item, &end, 0); + if (*end == '\0') + requested_settings.play_sample_rate = value ? fps_to_ratecode(value) : 0; + } + + item = get_driver_parameter (settings_handle, "play_buffer_frames", "0", "10240"); + 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", "0", "4"); + value = strtoul (item, &end, 0); + if (*end == '\0') + requested_settings.play_buffer_count = value; + + item = get_driver_parameter (settings_handle, "record_sample_rate", "0", "192000"); + value = strtoul (item, &end, 0); + if (*end == '\0') + requested_settings.record_sample_rate = value ? fps_to_ratecode(value) : 0; + + item = get_driver_parameter (settings_handle, "record_buffer_frames", "0", "10240"); + value = strtoul (item, &end, 0); + if (*end == '\0') + requested_settings.record_buffer_frames = value; + + item = get_driver_parameter (settings_handle, "record_buffer_count", "0", "4"); + 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) { @@ -107,6 +206,9 @@ get_description(hda_audio_group* audioGroup, multi_description* data) data->output_rates = 0; data->output_formats = 0; } + + if (requested_settings.play_sample_rate != 0) + data->output_rates = requested_settings.play_sample_rate; if (audioGroup->record_stream != NULL) { data->input_rates = audioGroup->record_stream->sample_rate; @@ -116,6 +218,9 @@ get_description(hda_audio_group* audioGroup, multi_description* data) data->input_formats = 0; } + if (requested_settings.record_sample_rate != 0) + data->input_rates = requested_settings.record_sample_rate; + // force existance of 48kHz if variable rates are not supported if (data->output_rates == 0) data->output_rates = B_SR_48000; @@ -865,6 +970,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: %ld buffers, %ld channels, %ld samples\n", data->request_playback_buffers, data->request_playback_channels, data->request_playback_buffer_size); diff --git a/src/apps/cortex/RouteApp/RouteAppNodeManager.cpp b/src/apps/cortex/RouteApp/RouteAppNodeManager.cpp index 0199bb9e8e..4b4b4d7afc 100644 --- a/src/apps/cortex/RouteApp/RouteAppNodeManager.cpp +++ b/src/apps/cortex/RouteApp/RouteAppNodeManager.cpp @@ -192,6 +192,8 @@ void RouteAppNodeManager::nodeCreated( if(err == B_OK) { BTimeSource* ts = roster->MakeTimeSourceFor(ref->node()); + if (ts == NULL) + return; if(ts->Node() != systemClock) { g->setTimeSource(ts->Node());