summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoursoir <chat@joursoir.net>2021-02-01 11:56:13 +0000
committerJoursoir <chat@joursoir.net>2021-02-01 11:56:13 +0000
commitbd71fe8e472671eb938092bb53086523aa06e4b0 (patch)
treef0d48f44f129a5ab99c8700dba30ba25d623b7f3
parent89e9b51764e9784dcfdf477ed85985b466d384f0 (diff)
downloadaudio-tools-bd71fe8e472671eb938092bb53086523aa06e4b0.tar.gz
audio-tools-bd71fe8e472671eb938092bb53086523aa06e4b0.tar.bz2
audio-tools-bd71fe8e472671eb938092bb53086523aa06e4b0.zip
add code for work with device, functional arg --list-devices
-rw-r--r--parecord/Makefile2
-rw-r--r--parecord/device.c142
-rw-r--r--parecord/device.h12
-rw-r--r--parecord/parecord.c32
4 files changed, 186 insertions, 2 deletions
diff --git a/parecord/Makefile b/parecord/Makefile
index 05ed2fc..6468280 100644
--- a/parecord/Makefile
+++ b/parecord/Makefile
@@ -1,6 +1,6 @@
CFLAGS = -Wall -g
PULSEFLAGS = -lpulse -lpulse-simple
-SOURCES = parecord.c audio_types.c
+SOURCES = parecord.c audio_types.c device.c
OBJECTS = ${SOURCES:.c=.o}
EXECUTABLE = parecord
diff --git a/parecord/device.c b/parecord/device.c
new file mode 100644
index 0000000..24f94ba
--- /dev/null
+++ b/parecord/device.c
@@ -0,0 +1,142 @@
+#include <string.h>
+#include <pulse/pulseaudio.h>
+#include <stdio.h>
+
+#include "device.h"
+
+static struct list_devices *g_input; // struct array
+static int input_idx;
+static int input_num; // size of struct array
+
+static void context_state_callback(pa_context *c, void *userdata)
+{
+ int *ready = userdata;
+
+ switch(pa_context_get_state(c)) {
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+
+ case PA_CONTEXT_READY: {
+ *ready = 1;
+ break;
+ }
+
+ case PA_CONTEXT_TERMINATED:
+ case PA_CONTEXT_FAILED:
+ default: {
+ *ready = 2;
+ // error
+ break;
+ }
+ }
+}
+
+static void context_sourcelist_callback(pa_context *c,
+ const pa_source_info *i, int eol, void *userdata)
+{
+ // end of list
+ if(eol > 0)
+ return;
+
+ if(input_idx >= input_num)
+ {
+ int i;
+ struct list_devices *tmp = malloc(
+ sizeof(struct list_devices) * (input_num+1));
+
+ for(i = 0; i < input_num; i++) {
+ tmp[i].name = g_input[i].name;
+ tmp[i].description = g_input[i].description;
+ }
+ input_num++;
+ free(g_input);
+ g_input = tmp;
+ }
+ g_input[input_idx].name
+ = malloc((strlen(i->name)+1)*sizeof(char));
+ strcpy(g_input[input_idx].name, i->name);
+
+ g_input[input_idx].description
+ = malloc((strlen(i->description)+1)*sizeof(char));
+ strcpy(g_input[input_idx].description, i->description);
+
+ input_idx++;
+}
+
+struct list_devices *getInputDeviceList(int *len)
+{
+ pa_mainloop *ml;
+ pa_mainloop_api *ml_api;
+ pa_context *context;
+ pa_operation *operation;
+ int state = 0;
+ int ready = 0;
+
+ if(!(ml = pa_mainloop_new()))
+ return NULL;
+ ml_api = pa_mainloop_get_api(ml);
+ context = pa_context_new(ml_api, NULL);
+
+ // Connect the context
+ if(pa_context_connect(context, NULL, 0, NULL) < 0)
+ return NULL;
+ pa_context_set_state_callback(context, context_state_callback, &ready);
+
+ input_idx = 0;
+ input_num = 3;
+ g_input = malloc(
+ sizeof(struct list_devices) * input_num);
+
+ for(;;) {
+ if(ready == 0) {
+ pa_mainloop_iterate(ml, 1, NULL);
+ continue;
+ }
+ if(ready == 2) {
+ pa_context_disconnect(context);
+ pa_context_unref(context);
+ pa_mainloop_free(ml);
+ return NULL;
+ }
+
+ switch(state) {
+ case 0: {
+ operation = pa_context_get_source_info_list(
+ context, context_sourcelist_callback, NULL);
+
+ state++;
+ break;
+ }
+ case 1: {
+ if(pa_operation_get_state(operation) == PA_OPERATION_DONE) {
+ pa_operation_unref(operation);
+ pa_context_disconnect(context);
+ pa_context_unref(context);
+ pa_mainloop_free(ml);
+ *len = input_num;
+ return g_input;
+ }
+ break;
+ }
+ default: {
+ pa_mainloop_free(ml);
+ return NULL;
+ }
+ }
+ pa_mainloop_iterate(ml, 1, NULL);
+ }
+}
+
+void freeDeviceList(struct list_devices *list, int len)
+{
+ int i;
+ for(i = 0; i < len; i++)
+ {
+ free(list[i].name);
+ free(list[i].description);
+ }
+ free(list);
+}
+
diff --git a/parecord/device.h b/parecord/device.h
new file mode 100644
index 0000000..3a520d6
--- /dev/null
+++ b/parecord/device.h
@@ -0,0 +1,12 @@
+#ifndef PAR_DEVICE_H
+#define PAR_DEVICE_H
+
+struct list_devices {
+ char *name;
+ char *description;
+};
+
+struct list_devices *getInputDeviceList(int *len);
+void freeDeviceList(struct list_devices *list, int len);
+
+#endif /* PAR_DEVICE_H */
diff --git a/parecord/parecord.c b/parecord/parecord.c
index feda84b..e14cea9 100644
--- a/parecord/parecord.c
+++ b/parecord/parecord.c
@@ -10,6 +10,7 @@
#include <pulse/simple.h>
#include "audio_types.h"
+#include "device.h"
#define PAR_RATE_MIN 2000U
#define PAR_CHANNELS_MIN 1U
@@ -63,6 +64,8 @@ int main(int argc, char *argv[])
off_t offset;
const struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
+ {"device", required_argument, NULL, 'd'},
+ {"list-devices", no_argument, NULL, 'D'},
{"file-type", required_argument, NULL, 't'},
{"file-types", no_argument, NULL, 'T'},
{"format", required_argument, NULL, 'f'},
@@ -72,7 +75,7 @@ int main(int argc, char *argv[])
{NULL, 0, NULL, 0}
};
- while((result = getopt_long(argc, argv, "ht:Tf:Fc:r:",
+ while((result = getopt_long(argc, argv, "hd:Dt:Tf:Fc:r:",
long_options, NULL)) != -1) {
switch(result) {
case 'h': {
@@ -81,6 +84,12 @@ int main(int argc, char *argv[])
fprintf(stderr, "Option:\n\t-h, --help\n");
fprintf(stderr, "\t\tPrint this text.\n");
+ fprintf(stderr, "\t-d, --device\n");
+ fprintf(stderr, "\t\tIn development...\n");
+
+ fprintf(stderr, "\t-D, --list-devices\n");
+ fprintf(stderr, "\t\tPrint all recorder audio devices\n");
+
fprintf(stderr, "\t-t, --file-type\n");
fprintf(stderr, "\t\tFile type (pcm, wav). PCM is used by default\n");
@@ -100,6 +109,27 @@ int main(int argc, char *argv[])
fprintf(stderr, "\t\tSample rate in Hz. %d Hz is used by default. \n", STD_REC_RATE);
return 0;
}
+ case 'd': {
+ // ...
+ break;
+ }
+ case 'D': {
+ int i, list_devices_len;
+ struct list_devices *input_devices
+ = getInputDeviceList(&list_devices_len);
+
+ if(!input_devices)
+ return 1;
+
+ fprintf(stderr, "**** Input devices ****\n");
+ for(i = 0; i < list_devices_len; i++) {
+ fprintf(stderr, "device %d: %s\n", i+1, input_devices[i].name);
+ fprintf(stderr, "\t%s\n", input_devices[i].description);
+ }
+
+ freeDeviceList(input_devices, list_devices_len);
+ return 0;
+ }
case 't': {
file_type = checkAudioType(optarg);
if(file_type != AUDIO_TYPE_NONE) break;