UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
alsa_common.h File Reference
#include <alsa/asoundlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"
#include "utils/color_out.h"
#include "types.h"
Include dependency graph for alsa_common.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static const char * alsa_get_pcm_state_name (snd_pcm_state_t state) __attribute__((unused))
 
static void audio_alsa_list_devices (void)
 
static void audio_alsa_probe (struct device_info **available_devices, int *count, const char **whitelist, size_t whitelist_size)
 
static int get_rate_near (snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int approx_val)
 
static void print_alsa_device_info (snd_pcm_t *handle, const char *module_name)
 

Variables

static const snd_pcm_format_t bps_to_snd_fmts []
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file alsa_common.h.

Function Documentation

◆ alsa_get_pcm_state_name()

static const char * alsa_get_pcm_state_name ( snd_pcm_state_t state)
static

Definition at line 208 of file alsa_common.h.

208 {
209 switch (state) {
210 case SND_PCM_STATE_OPEN:
211 return "Open";
212 case SND_PCM_STATE_SETUP:
213 return "Setup installed";
214 case SND_PCM_STATE_PREPARED:
215 return "Ready to start";
216 case SND_PCM_STATE_RUNNING:
217 return "Running";
218 case SND_PCM_STATE_XRUN:
219 return "Stopped: underrun (playback) or overrun (capture) detected";
220 case SND_PCM_STATE_DRAINING:
221 return "Draining: running (playback) or stopped (capture)";
222 case SND_PCM_STATE_PAUSED:
223 return "Paused";
224 case SND_PCM_STATE_SUSPENDED:
225 return "Hardware is suspended";
226 case SND_PCM_STATE_DISCONNECTED:
227 return "Hardware is disconnected";
228 default:
229 return "(unknown)";
230 }
231}
void ** state

References state.

Referenced by audio_play_alsa_put_frame(), and audio_play_alsa_reconfigure().

◆ audio_alsa_list_devices()

static void audio_alsa_list_devices ( void )
inlinestatic

Definition at line 114 of file alsa_common.h.

115{
116 struct device_info *available_devices;
117 int count;
118 audio_alsa_probe(&available_devices, &count, NULL, 0);
119 strcpy(available_devices[0].dev, "");
120 strcpy(available_devices[0].name, "default ALSA device (same as \"alsa:default\")");
121 for(int i = 0; i < count; i++){
122 const char * const id = available_devices[i].dev;
123 color_printf(TERM_FG_RED "\talsa%s" TERM_FG_RESET, id);
124 for (int j = 0; j < 30 - (int) strlen(id); ++j) putchar(' ');
125 printf(": %s\n", available_devices[i].name);
126 }
127 free(available_devices);
128}
static void audio_alsa_probe(struct device_info **available_devices, int *count, const char **whitelist, size_t whitelist_size)
Definition alsa_common.h:50
int color_printf(const char *format,...)
#define TERM_FG_RED
Definition color_out.h:50
#define TERM_FG_RESET
Definition color_out.h:59
int count
Definition hd-rum.c:44
const char * name
Definition settings.cpp:193
char dev[1024]
Definition types.h:383

References audio_alsa_probe(), color_printf(), count, device_info::dev, name, TERM_FG_RED, and TERM_FG_RESET.

Referenced by audio_cap_alsa_help(), and audio_play_alsa_help().

Here is the call graph for this function:

◆ audio_alsa_probe()

static void audio_alsa_probe ( struct device_info ** available_devices,
int * count,
const char ** whitelist,
size_t whitelist_size )
inlinestatic

Definition at line 50 of file alsa_common.h.

54{
55 void **hints;
56 snd_device_name_hint(-1, "pcm", &hints);
57
58 size_t device_count = 0;
59 for (void **it = hints; *it != NULL; it++) device_count++;
60
61 *available_devices = calloc(device_count + 1 , sizeof(struct device_info));
62 strcpy((*available_devices)[0].dev, "");
63 strcpy((*available_devices)[0].name, "Default Linux audio");
64 *count = 1;
65
66 for(void **it = hints; *it != NULL; it++){
67 char *id = snd_device_name_get_hint(*it, "NAME");
68
69 bool whitelisted = false;
70 for(size_t i = 0; i < whitelist_size; i++){
71 if(strstr(id, whitelist[i])){
72 whitelisted = true;
73 break;
74 }
75 }
76 if(!whitelisted && whitelist_size > 0) {
77 free(id);
78 continue;
79 }
80
81 strcpy((*available_devices)[*count].dev, ":");
82 strncat((*available_devices)[*count].dev, id,
83 sizeof (*available_devices)[*count].dev -
84 strlen((*available_devices)[*count].dev) - 1);
85 free(id);
86
87 char *name = snd_device_name_get_hint(*it, "DESC");
88 char *tok = name;
89 while(tok){
90 char *newline = strchr(tok, '\n');
91 if(newline){
92 *newline = '\0';
93 strncat((*available_devices)[*count].name, tok,
94 sizeof (*available_devices)[*count].name -
95 strlen((*available_devices)[*count].name) - 1);
96 strncat((*available_devices)[*count].name, " - ",
97 sizeof (*available_devices)[*count].name -
98 strlen((*available_devices)[*count].name) - 1);
99 tok = newline + 1;
100 } else {
101 strncat((*available_devices)[*count].name, tok,
102 sizeof (*available_devices)[*count].name -
103 strlen((*available_devices)[*count].name) - 1);
104 tok = NULL;
105 }
106 }
107 free(name);
108 (*count)++;
109 }
110
111 snd_device_name_free_hint(hints);
112}

References count, and name.

Referenced by audio_alsa_list_devices(), audio_cap_alsa_probe(), and audio_play_alsa_probe().

◆ get_rate_near()

static int get_rate_near ( snd_pcm_t * handle,
snd_pcm_hw_params_t * params,
unsigned int approx_val )
static

Finds equal or nearest higher sample rate that device supports. If none exist, pick highest lower value.

Returns
sample rate, 0 if none was found

Definition at line 144 of file alsa_common.h.

144 {
145 int ret = 0;
146 int dir = 0;
147 int rc;
148 unsigned int rate = approx_val;
149 // try exact sample rate
150 rc = snd_pcm_hw_params_set_rate_min(handle, params, &rate, &dir);
151 if (rc != 0) {
152 dir = 1;
153 // or higher
154 rc = snd_pcm_hw_params_set_rate_min(handle, params, &rate, &dir);
155 }
156
157 if (rc == 0) {
158 // read the rate
159 rc = snd_pcm_hw_params_get_rate_min(params, &rate, NULL);
160 if (rc == 0) {
161 ret = rate;
162 }
163 // restore configuration space
164 rate = 0;
165 dir = 1;
166 rc = snd_pcm_hw_params_set_rate_min(handle, params, &rate, &dir);
167 assert(rc == 0);
168 }
169
170 // we did not succeed, try lower sample rate
171 if (ret == 0) {
172 unsigned int rate = approx_val;
173 dir = 0;
174 unsigned int orig_max;
175 rc = snd_pcm_hw_params_get_rate_max(params, &orig_max, NULL);
176 assert(rc == 0);
177
178 rc = snd_pcm_hw_params_set_rate_max(handle, params, &rate, &dir);
179 if (rc != 0) {
180 dir = -1;
181 rc = snd_pcm_hw_params_set_rate_max(handle, params, &rate, &dir);
182 }
183
184 if (rc == 0) {
185 rc = snd_pcm_hw_params_get_rate_max(params, &rate, NULL);
186 if (rc == 0) {
187 ret = rate;
188 }
189 // restore configuration space
190 dir = 0;
191 rc = snd_pcm_hw_params_set_rate_max(handle, params, &orig_max, &dir);
192 assert(rc == 0);
193 }
194 }
195 return ret;
196}

Referenced by audio_cap_alsa_init(), and audio_play_alsa_query_format().

◆ print_alsa_device_info()

static void print_alsa_device_info ( snd_pcm_t * handle,
const char * module_name )
static

Definition at line 198 of file alsa_common.h.

198 {
199 snd_pcm_info_t *info;
200 snd_pcm_info_alloca(&info);
201 if (snd_pcm_info(handle, info) == 0) {
202 log_msg(LOG_LEVEL_NOTICE, "%sUsing device: %s\n",
203 module_name, snd_pcm_info_get_name(info));
204 }
205}
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61

References LOG_LEVEL_NOTICE, and log_msg().

Referenced by audio_cap_alsa_init(), and audio_play_alsa_init().

Here is the call graph for this function:

Variable Documentation

◆ bps_to_snd_fmts

const snd_pcm_format_t bps_to_snd_fmts[]
static
Initial value:
= {
[0] = SND_PCM_FORMAT_UNKNOWN,
[1] = SND_PCM_FORMAT_U8,
[2] = SND_PCM_FORMAT_S16_LE,
[3] = SND_PCM_FORMAT_S24_3LE,
[4] = SND_PCM_FORMAT_S32_LE,
}

Definition at line 130 of file alsa_common.h.

130 {
131 [0] = SND_PCM_FORMAT_UNKNOWN,
132 [1] = SND_PCM_FORMAT_U8,
133 [2] = SND_PCM_FORMAT_S16_LE,
134 [3] = SND_PCM_FORMAT_S24_3LE,
135 [4] = SND_PCM_FORMAT_S32_LE,
136};

Referenced by audio_cap_alsa_init(), audio_play_alsa_query_format(), and audio_play_alsa_reconfigure().