mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-22 18:58:21 +00:00
(tinyalsa) Add error handling for sample rate.
This commit is contained in:
parent
e58eee37bc
commit
175aaadb0d
@ -664,30 +664,6 @@ static void param_set_min(struct snd_pcm_hw_params *p, int n, unsigned int val)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Unused for now */
|
||||
|
||||
static unsigned int param_get_min(const struct snd_pcm_hw_params *p, int n)
|
||||
{
|
||||
if (param_is_interval(n))
|
||||
{
|
||||
const struct snd_interval *i = param_get_interval(p, n);
|
||||
return i->min;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int param_get_max(const struct snd_pcm_hw_params *p, int n)
|
||||
{
|
||||
if (param_is_interval(n))
|
||||
{
|
||||
const struct snd_interval *i = param_get_interval(p, n);
|
||||
return i->max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned int val)
|
||||
{
|
||||
if (param_is_interval(n))
|
||||
@ -1525,9 +1501,6 @@ static struct pcm bad_pcm = {
|
||||
-1 /* fd */
|
||||
};
|
||||
|
||||
#if 0
|
||||
/* Unused for now */
|
||||
|
||||
/** Gets the hardware parameters of a PCM, without created a PCM handle.
|
||||
* @param card The card of the PCM.
|
||||
* The default card is zero.
|
||||
@ -1593,6 +1566,9 @@ static void pcm_params_free(struct pcm_params *pcm_params)
|
||||
free(params);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Unused for now */
|
||||
|
||||
/** Gets a mask from a PCM's hardware parameters.
|
||||
* @param pcm_params A PCM's hardware parameters.
|
||||
* @param param The parameter to get.
|
||||
@ -1614,50 +1590,7 @@ static const struct pcm_mask *pcm_params_get_mask(const struct pcm_params *pcm_p
|
||||
|
||||
return (const struct pcm_mask *)param_to_mask(params, p);
|
||||
}
|
||||
|
||||
/** Get the minimum of a specified PCM parameter.
|
||||
* @param pcm_params A PCM parameters structure.
|
||||
* @param param The specified parameter to get the minimum of.
|
||||
* @returns On success, the parameter minimum.
|
||||
* On failure, zero.
|
||||
*/
|
||||
static unsigned int pcm_params_get_min(const struct pcm_params *pcm_params,
|
||||
enum pcm_param param)
|
||||
{
|
||||
struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
|
||||
int p;
|
||||
|
||||
if (!params)
|
||||
return 0;
|
||||
|
||||
p = pcm_param_to_alsa(param);
|
||||
if (p < 0)
|
||||
return 0;
|
||||
|
||||
return param_get_min(params, p);
|
||||
}
|
||||
|
||||
/** Get the maximum of a specified PCM parameter.
|
||||
* @param pcm_params A PCM parameters structure.
|
||||
* @param param The specified parameter to get the maximum of.
|
||||
* @returns On success, the parameter maximum.
|
||||
* On failure, zero.
|
||||
*/
|
||||
static unsigned int pcm_params_get_max(const struct pcm_params *pcm_params,
|
||||
enum pcm_param param)
|
||||
{
|
||||
const struct snd_pcm_hw_params *params = (const struct snd_pcm_hw_params *)pcm_params;
|
||||
int p;
|
||||
|
||||
if (!params)
|
||||
return 0;
|
||||
|
||||
p = pcm_param_to_alsa(param);
|
||||
if (p < 0)
|
||||
return 0;
|
||||
|
||||
return param_get_max(params, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pcm_param_to_alsa(enum pcm_param param)
|
||||
{
|
||||
@ -1700,8 +1633,70 @@ static int pcm_param_to_alsa(enum pcm_param param)
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int param_get_min(const struct snd_pcm_hw_params *p, int n)
|
||||
{
|
||||
if (param_is_interval(n))
|
||||
{
|
||||
const struct snd_interval *i = param_get_interval(p, n);
|
||||
return i->min;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Get the minimum of a specified PCM parameter.
|
||||
* @param pcm_params A PCM parameters structure.
|
||||
* @param param The specified parameter to get the minimum of.
|
||||
* @returns On success, the parameter minimum.
|
||||
* On failure, zero.
|
||||
*/
|
||||
static unsigned int pcm_params_get_min(const struct pcm_params *pcm_params,
|
||||
enum pcm_param param)
|
||||
{
|
||||
struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
|
||||
int p;
|
||||
|
||||
if (!params)
|
||||
return 0;
|
||||
|
||||
p = pcm_param_to_alsa(param);
|
||||
if (p < 0)
|
||||
return 0;
|
||||
|
||||
return param_get_min(params, p);
|
||||
}
|
||||
|
||||
static unsigned int param_get_max(const struct snd_pcm_hw_params *p, int n)
|
||||
{
|
||||
if (param_is_interval(n))
|
||||
{
|
||||
const struct snd_interval *i = param_get_interval(p, n);
|
||||
return i->max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Get the maximum of a specified PCM parameter.
|
||||
* @param pcm_params A PCM parameters structure.
|
||||
* @param param The specified parameter to get the maximum of.
|
||||
* @returns On success, the parameter maximum.
|
||||
* On failure, zero.
|
||||
*/
|
||||
static unsigned int pcm_params_get_max(const struct pcm_params *pcm_params,
|
||||
enum pcm_param param)
|
||||
{
|
||||
const struct snd_pcm_hw_params *params = (const struct snd_pcm_hw_params *)pcm_params;
|
||||
int p;
|
||||
|
||||
if (!params)
|
||||
return 0;
|
||||
|
||||
p = pcm_param_to_alsa(param);
|
||||
if (p < 0)
|
||||
return 0;
|
||||
|
||||
return param_get_max(params, p);
|
||||
}
|
||||
|
||||
/** Stops a PCM.
|
||||
* @param pcm A PCM handle.
|
||||
@ -2135,6 +2130,7 @@ static int pcm_mmap_transfer_areas(struct pcm *pcm, char *buf,
|
||||
typedef struct tinyalsa
|
||||
{
|
||||
struct pcm *pcm;
|
||||
struct pcm_params *params;
|
||||
size_t buffer_size;
|
||||
bool nonblock;
|
||||
bool has_float;
|
||||
@ -2150,12 +2146,53 @@ static void * tinyalsa_init(const char *devicestr, unsigned rate,
|
||||
unsigned latency, unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
unsigned int card = 0;
|
||||
unsigned int device = 0;
|
||||
unsigned int orig_rate = rate;
|
||||
unsigned int max_rate, min_rate;
|
||||
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
struct pcm_config config;
|
||||
|
||||
tinyalsa_t *tinyalsa = (tinyalsa_t*)calloc(1, sizeof(tinyalsa_t));
|
||||
|
||||
if (!tinyalsa)
|
||||
return NULL;
|
||||
|
||||
if (devicestr)
|
||||
sscanf(devicestr, "%u,%u", &card, &device);
|
||||
|
||||
RARCH_LOG("[TINYALSA]: Using card: %u, device: %u.\n", card, device);
|
||||
|
||||
tinyalsa->params = pcm_params_get(card, device, PCM_OUT);
|
||||
if (tinyalsa->params == NULL)
|
||||
{
|
||||
RARCH_ERR("[TINYALSA]: params: Cannot open audio device.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
min_rate = pcm_params_get_min(tinyalsa->params, PCM_PARAM_RATE);
|
||||
max_rate = pcm_params_get_max(tinyalsa->params, PCM_PARAM_RATE);
|
||||
|
||||
if (!(rate >= min_rate && rate <= max_rate))
|
||||
{
|
||||
RARCH_WARN("[TINYALSA]: Sample rate cannot be larger than %uHz "\
|
||||
"or smaller than %uHz.\n", max_rate, min_rate);
|
||||
RARCH_WARN("[TINYALSA]: Trying the default rate or else max rate.\n");
|
||||
|
||||
if (max_rate >= 48000)
|
||||
{
|
||||
rate = 48000;
|
||||
}
|
||||
else
|
||||
{
|
||||
rate = max_rate;
|
||||
}
|
||||
}
|
||||
|
||||
if (orig_rate != rate)
|
||||
*new_rate = rate;
|
||||
|
||||
config.rate = rate;
|
||||
config.format = PCM_FORMAT_S16_LE;
|
||||
config.channels = 2;
|
||||
@ -2165,14 +2202,6 @@ static void * tinyalsa_init(const char *devicestr, unsigned rate,
|
||||
config.stop_threshold = 1024 * 2;
|
||||
config.silence_threshold = 1024 * 2;
|
||||
|
||||
unsigned int card = 0;
|
||||
unsigned int device = 0;
|
||||
|
||||
if (devicestr)
|
||||
sscanf(devicestr, "%u,%u", &card, &device);
|
||||
|
||||
RARCH_LOG("[TINYALSA]: Using card: %u, device: %u.\n", card, device);
|
||||
|
||||
tinyalsa->pcm = pcm_open(card, device, PCM_OUT, &config);
|
||||
|
||||
if (tinyalsa->pcm == NULL)
|
||||
@ -2329,8 +2358,11 @@ static void tinyalsa_free(void *data)
|
||||
|
||||
if (tinyalsa)
|
||||
{
|
||||
pcm_params_free(tinyalsa->params);
|
||||
|
||||
if (tinyalsa->pcm)
|
||||
pcm_close(tinyalsa->pcm);
|
||||
|
||||
tinyalsa->pcm = NULL;
|
||||
free(tinyalsa);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user