Commit 825613b7 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Allow mixers to be identified by device name, where possible

Detail:
  c/module - If a version of SoundDMA is in use which supports the device enumeration/selection APIs, allow mixers to be identified by name rather than by number.
  SoundDMA will be relied upon for name resolution, allowing stable device names/IDs to be used rather than the unstable numbering system.
  For compatibility, "0" (for *commands) and NULL (for SWIs) will be interpreted as a reference to the mixer for the current default audio device.
  Also fix AddDevice not filling in the device number when adding the new device.
Admin:
  Tested on iMX6


Version 1.04. Tagged as 'SoundCtrl-1_04'
parent b7184473
/* (1.03)
/* (1.04)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 1.03
#define Module_MajorVersion_CMHG 1.04
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 15 Aug 2012
#define Module_Date_CMHG 01 Dec 2015
#define Module_MajorVersion "1.03"
#define Module_Version 103
#define Module_MajorVersion "1.04"
#define Module_Version 104
#define Module_MinorVersion ""
#define Module_Date "15 Aug 2012"
#define Module_Date "01 Dec 2015"
#define Module_ApplicationDate "15-Aug-12"
#define Module_ApplicationDate "01-Dec-15"
#define Module_ComponentName "SoundCtrl"
#define Module_ComponentPath "castle/RiscOS/Sources/Audio/SoundCtrl"
#define Module_FullVersion "1.03"
#define Module_HelpVersion "1.03 (15 Aug 2012)"
#define Module_LibraryVersionInfo "1:3"
#define Module_FullVersion "1.04"
#define Module_HelpVersion "1.04 (01 Dec 2015)"
#define Module_LibraryVersionInfo "1:4"
......@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <ctype.h>
#include <inttypes.h>
#include "kernel.h"
#include "swis.h"
......@@ -23,6 +24,7 @@
#include "Global/HALDevice.h"
#include "Global/Services.h"
#include "Interface/MixerDevice.h"
#include "Interface/Sound.h"
#include "DebugLib/DebugLib.h"
#include "global.h"
......@@ -48,8 +50,10 @@ static void MixVolumeCommand(const char *arg_string, int argc);
static _kernel_oserror *ExamineMixerSWI(_kernel_swi_regs *r);
static _kernel_oserror *SetMixSWI(_kernel_swi_regs *r);
static _kernel_oserror *GetMixSWI(_kernel_swi_regs *r);
static _kernel_oserror *FindChannel(uint32_t system_num, int32_t category, uint32_t index, system_t **system, uint32_t *channel);
static _kernel_oserror *FindSystemBlock(uint32_t system_num, system_t **system);
static _kernel_oserror *FindChannel(system_t *system, int32_t category, uint32_t index, uint32_t *channel);
static _kernel_oserror *FindSystemBlockByNumber(uint32_t system_num, system_t **system);
static _kernel_oserror *FindSystemBlockByDevice(struct mixer_device *device, system_t **system);
static _kernel_oserror *FindSystemBlockForSWI(int r0, system_t **system);
static system_t *static_SystemList = NULL;
......@@ -290,6 +294,7 @@ static void AddDevice(struct mixer_device *device)
prev = next;
next = next->next;
}
system->number = expected_number;
system->next = next;
if (prev)
{
......@@ -333,21 +338,83 @@ static void RemoveDevice(struct mixer_device *device)
}
static bool SoundDMA_DeviceSelection(void)
{
uint32_t ret,flags;
/* Check if device selection & enumeration functionality is available */
if (_swix(Sound_ReadSysInfo, _IN(0)|_OUTR(0,1), Sound_RSI_Features, &ret, &flags))
{
dprintf(("", "DeviceSelection: SWI error\n"));
return false;
}
if (ret || !(flags & Sound_RSI_Feature_DeviceSelection))
{
dprintf(("", "DeviceSelection: no\n"));
return false;
}
dprintf(("", "DeviceSelection: yes\n"));
return true;
}
static void MixVolumeCommand(const char *arg_string, int argc)
{
uint32_t system_num;
int32_t category;
uint32_t index;
unsigned char mute;
int32_t gain;
system_t *system;
system_t *system = NULL;
uint32_t channel;
if (SoundDMA_DeviceSelection())
{
/* Accept "0" or a device ID */
struct mixer_device *device;
char temp[128];
const char *device_id;
if ((arg_string[0] == '0') && isspace(arg_string[0]))
{
/* Get current device ID */
if (_swix(Sound_ReadSysInfo, _INR(0,2), Sound_RSI_DefaultDevice, temp, sizeof(temp)))
{
return;
}
device_id = temp;
}
else
{
device_id = arg_string;
}
dprintf(("", "Looking for mixer for '%s'\n",device_id));
/* Get mixer from device ID */
if (_swix(Sound_DeviceInfo, _INR(0,3), device_id, &device, sizeof(device), Sound_DevInfo_MixerDevice))
{
return;
}
FindSystemBlockByDevice(device, &system);
}
else
{
/* Old SoundDMA, accept mixer number (using internal numbering scheme) */
FindSystemBlockByNumber(atoi(arg_string), &system);
}
if (!system)
{
return;
}
while (*arg_string && !isspace(*arg_string))
{
arg_string++;
}
if (argc == 4)
{
if (sscanf(arg_string, "%"SCNu32" %"SCNd32" %"SCNu32" %c", &system_num, &category, &index, &mute) == 4)
if (sscanf(arg_string, "%"SCNd32" %"SCNu32" %c", &category, &index, &mute) == 3)
{
mute -= '0';
if (mute <= 1 && FindChannel(system_num, category, index, &system, &channel) == 0)
if (mute <= 1 && FindChannel(system, category, index, &channel) == 0)
{
struct mixer_device_channel_state state = system->device->GetMix(system->device, channel);
state.mute = mute;
......@@ -357,10 +424,10 @@ static void MixVolumeCommand(const char *arg_string, int argc)
}
else /* argc == 5 */
{
if (sscanf(arg_string, "%"SCNu32" %"SCNd32" %"SCNu32" %c %"SCNd32, &system_num, &category, &index, &mute, &gain) == 5)
if (sscanf(arg_string, "%"SCNd32" %"SCNu32" %c %"SCNd32, &category, &index, &mute, &gain) == 4)
{
mute -= '0';
if (mute <= 1 && FindChannel(system_num, category, index, &system, &channel) == 0)
if (mute <= 1 && FindChannel(system, category, index, &channel) == 0)
{
struct mixer_device_channel_state state = { mute, gain };
system->device->SetMix(system->device, channel, state);
......@@ -374,7 +441,7 @@ static void MixVolumeCommand(const char *arg_string, int argc)
static _kernel_oserror *ExamineMixerSWI(_kernel_swi_regs *r)
{
system_t *system;
_kernel_oserror *e = FindSystemBlock((uint32_t) r->r[0], &system);
_kernel_oserror *e = FindSystemBlockForSWI((uint32_t) r->r[0], &system);
if (e) return e;
uint32_t nchannels = system->device->nchannels;
......@@ -409,7 +476,10 @@ static _kernel_oserror *SetMixSWI(_kernel_swi_regs *r)
{
system_t *system;
uint32_t channel;
_kernel_oserror *e = FindChannel((uint32_t) r->r[0], (int32_t) r->r[1], (uint32_t) r->r[2], &system, &channel);
_kernel_oserror *e = FindSystemBlockForSWI(r->r[0], &system);
if (e) return e;
e = FindChannel(system, (int32_t) r->r[1], (uint32_t) r->r[2], &channel);
if (e) return e;
struct mixer_device_channel_state state = { r->r[3], r->r[4] };
......@@ -423,7 +493,10 @@ static _kernel_oserror *GetMixSWI(_kernel_swi_regs *r)
{
system_t *system;
uint32_t channel;
_kernel_oserror *e = FindChannel((uint32_t) r->r[0], (int32_t) r->r[1], (uint32_t) r->r[2], &system, &channel);
_kernel_oserror *e = FindSystemBlockForSWI(r->r[0], &system);
if (e) return e;
e = FindChannel(system, (int32_t) r->r[1], (uint32_t) r->r[2], &channel);
if (e) return e;
struct mixer_device_channel_state state = system->device->GetMix(system->device, channel);
......@@ -434,17 +507,14 @@ static _kernel_oserror *GetMixSWI(_kernel_swi_regs *r)
}
static _kernel_oserror *FindChannel(uint32_t system_num, int32_t category, uint32_t index, system_t **system, uint32_t *channel)
static _kernel_oserror *FindChannel(system_t *system, int32_t category, uint32_t index, uint32_t *channel)
{
_kernel_oserror *e = FindSystemBlock(system_num, system);
if (e) return e;
uint32_t c = 0;
uint32_t nchannels = (*system)->device->nchannels;
uint32_t nchannels = system->device->nchannels;
struct mixer_device_channel_features features;
for (; c < nchannels; c++)
{
features = (*system)->device->GetFeatures((*system)->device, c);
features = system->device->GetFeatures(system->device, c);
if (features.category == category && index-- == 0) /* note second isn't performed if first test fails */
{
*channel = c;
......@@ -455,8 +525,9 @@ static _kernel_oserror *FindChannel(uint32_t system_num, int32_t category, uint3
}
static _kernel_oserror *FindSystemBlock(uint32_t system_num, system_t **system)
static _kernel_oserror *FindSystemBlockByNumber(uint32_t system_num, system_t **system)
{
dprintf(("","FindSystemBlockByNumber: %u\n",system_num));
system_t *s = static_SystemList;
for (; s != NULL; s = s->next)
{
......@@ -464,6 +535,7 @@ static _kernel_oserror *FindSystemBlock(uint32_t system_num, system_t **system)
}
if (s)
{
dprintf(("","Found\n"));
*system = s;
return NULL;
}
......@@ -472,3 +544,61 @@ static _kernel_oserror *FindSystemBlock(uint32_t system_num, system_t **system)
return mess_MakeError(error_SOUNDCTRL_BAD_MIXER, 0);
}
}
static _kernel_oserror *FindSystemBlockByDevice(struct mixer_device *device, system_t **system)
{
dprintf(("","FindSystemBlockByDevice: %x\n",device));
system_t *s = static_SystemList;
for (; s != NULL; s = s->next)
{
if (s->device == device) break;
}
if (s)
{
dprintf(("","Found\n"));
*system = s;
return NULL;
}
else
{
return mess_MakeError(error_SOUNDCTRL_BAD_MIXER, 0);
}
}
static _kernel_oserror *FindSystemBlockForSWI(int r0, system_t **system)
{
_kernel_oserror *e;
if (SoundDMA_DeviceSelection())
{
/* Accept NULL or a string pointer */
struct mixer_device *device;
char temp[128];
char *device_id;
if (!r0)
{
/* Get current device ID */
if ((e = _swix(Sound_ReadSysInfo, _INR(0,2), Sound_RSI_DefaultDevice, temp, sizeof(temp))) != NULL)
{
return e;
}
device_id = temp;
}
else
{
device_id = (char *) r0;
}
dprintf(("", "Looking for mixer for '%s'\n",device_id));
/* Get mixer from device ID */
if ((e = _swix(Sound_DeviceInfo, _INR(0,3), device_id, &device, sizeof(device), Sound_DevInfo_MixerDevice)) != NULL)
{
return e;
}
return FindSystemBlockByDevice(device, system);
}
else
{
/* Old SoundDMA, accept mixer number (using internal numbering scheme) */
return FindSystemBlockByNumber(r0, system);
}
}
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