emitter and receptor confirmed to work. emitter only works with alsa backend

This commit is contained in:
Benoit Quiniou 2017-08-16 09:39:00 +02:00
parent 57beb269c7
commit 8fb752a0f8
4 changed files with 74 additions and 23 deletions

View File

@ -6,7 +6,7 @@ vban - Linux command-line VBAN tools
vban project is an open-source implementation of VBAN protocol.
VBAN is a simple audio over UDP protocol proposed by VB-Audio, see [VBAN Audio webpage](http://vb-audio.pagesperso-orange.fr/Voicemeeter/vban.htm).
It is composed of several command-line tools allowing to stream audio coming from audio backend interfaces to VBAN stream (vban_emitter) or playout incoming VBAN stream to audio backend interfaces (vban_receptor)
Up to now, Alsa, PulseAudio and Jack audio backends have been implemented. A fifo (pipe) output is also existing, to allow chaining command-line tools, its status is experimental.
Up to now, Alsa, PulseAudio and Jack audio backends have been implemented. A fifo (pipe) output is also existing, to allow chaining command-line tools, and a file output too (writing raw pcm data).
Compilation and installation
----------------------------
@ -20,9 +20,9 @@ Usual package names are:
vban is distributed with autotools build scripts, therefore, to build, you need to invoke:
$ ./autogen.sh # probably only once for ever
$ ./configure # with or without options (--help to get the list of possible options)
$ make # with or without options
$ ./autogen.sh # probably only once for ever
$ ./configure # with or without options (--help to get the list of possible options)
$ make # with or without options
To install, simply invoke:
@ -38,19 +38,37 @@ Usage
Invoking vban_receptor or vban_emitter without any parameter will give hints on how to use them :
Usage: vban_receptor [OPTIONS]...
Usage: vban [OPTIONS]...
-i, --ipaddress=IP : MANDATORY. ipaddress to get stream from
-p, --port=PORT : MANDATORY. port to listen to
-s, --streamname=NAME : MANDATORY. streamname to play
-b, --backend=TYPE : audio backend to use. possible values: alsa, pulseaudio, jack and pipe (EXPERIMENTAL). default is first in this list that is actually compiled
-b, --backend=TYPE : audio backend to use. Available audio backends are: alsa pulseaudio jack pipe file . default is alsa.
-q, --quality=ID : network quality indicator from 0 (low latency) to 4. default is 1
-c, --channels=LIST : channels from the stream to use. LIST is of form x,y,z,... default is to forward the stream as it is
-o, --output=NAME : Output device (server for jack backend) name , (as given by "aplay -L" output for alsa). using backend's default by default. not used for jack or pipe
-d, --debug=LEVEL : Log level, from 0 (FATAL) to 4 (DEBUG). default is 1 (ERROR)
-c, --channels=LIST : TEMPORARY DISABLED
-o, --output=NAME : DEPRECATED. please use -d
-d, --device=NAME : Audio device name. This is file name for file backend, server name for jack backend, device for alsa, stream_name for pulseaudio.
-l, --loglevel=LEVEL : Log level, from 0 (FATAL) to 4 (DEBUG). default is 1 (ERROR)
-h, --help : display this message
TODO: missing vban_emitter doc
Usage: vban_emitter [OPTIONS]...
-i, --ipaddress=IP : MANDATORY. ipaddress to send stream to
-p, --port=PORT : MANDATORY. port to use
-s, --streamname=NAME : MANDATORY. streamname to use
-b, --backend=TYPE : TEMPORARY DISABLED. audio backend to use. Only alsa backend is working at this time
-d, --device=NAME : Audio device name. This is file name for file backend, server name for jack backend, device for alsa, stream_name for pulseaudio.
-r, --rate=VALUE : Audio device sample rate. default 44100
-n, --nbchannels=VALUE : Audio device number of channels. default 2
-f, --format=VALUE : Audio device sample format (see below). default is 16I (16bits integer)
-c, --channels=LIST : TEMPORARY DISABLED.
-l, --loglevel=LEVEL : Log level, from 0 (FATAL) to 4 (DEBUG). default is 1 (ERROR)
-h, --help : display this message
Recognized bit format are 8I, 16I, 24I, 32I, 32F, 64F, 12I, 10I
Temporarily disabled
--------------------
About --channels option, a bit more tips:
* channels indexes are from 1 to 256 (as specified by VBAN specifications for vban_receptor, and well, its probably enough for any soundcard or jack configuration)
@ -63,4 +81,4 @@ Examples:
vban_receptor -i IP -p PORT -s STREAMNAME -c1 # keep only channel 1 and play out as mono
vban_receptor -i IP -p PORT -s STREAMNAME -c1,1,1,1 # keep only channel 1 and play it out on 4 output channels (given that your output device is able to do it)
vban_receptor -i IP -p PORT -s STREAMNAME -c2,41,125,7,1,45 # select some channels and play them out on 6 output channels (same comment)
vban_emitter -i IP -p PORT -s STREAMNAME -c1,1,1,1 # use audio source channel 1 (opening it in mono therefore, and build up a 4 channels stream with copies of the same data in all channels)
vban_emitter -i IP -p PORT -s STREAMNAME -c1,1,1,1 # use audio source channel 1 (opening it in mono therefore, and build up a 4 channels stream with copies of the same data in all channels)

View File

@ -10,9 +10,10 @@ struct pulseaudio_backend_t
pa_simple* pulseaudio_handle;
};
static int pulseaudio_open(audio_backend_handle_t handle, char const* output_name, enum audio_direction direction, size_t buffer_size, struct stream_config_t const* config);
static int pulseaudio_open(audio_backend_handle_t handle, char const* device_name, enum audio_direction direction, size_t buffer_size, struct stream_config_t const* config);
static int pulseaudio_close(audio_backend_handle_t handle);
static int pulseaudio_write(audio_backend_handle_t handle, char const* data, size_t size);
static int pulseaudio_read(audio_backend_handle_t handle, char* data, size_t size);
static enum pa_sample_format vban_to_pulseaudio_format(enum VBanBitResolution bit_resolution)
{
@ -59,6 +60,7 @@ int pulseaudio_backend_init(audio_backend_handle_t* handle)
pulseaudio_backend->parent.open = pulseaudio_open;
pulseaudio_backend->parent.close = pulseaudio_close;
pulseaudio_backend->parent.write = pulseaudio_write;
pulseaudio_backend->parent.read = pulseaudio_read;
*handle = (audio_backend_handle_t)pulseaudio_backend;
@ -66,7 +68,7 @@ int pulseaudio_backend_init(audio_backend_handle_t* handle)
}
int pulseaudio_open(audio_backend_handle_t handle, char const* output_name, enum audio_direction direction, size_t buffer_size, struct stream_config_t const* config)
int pulseaudio_open(audio_backend_handle_t handle, char const* device_name, enum audio_direction direction, size_t buffer_size, struct stream_config_t const* config)
{
int ret;
struct pulseaudio_backend_t* const pulseaudio_backend = (struct pulseaudio_backend_t*)handle;
@ -92,7 +94,8 @@ int pulseaudio_open(audio_backend_handle_t handle, char const* output_name, enum
return -EINVAL;
}
pulseaudio_backend->pulseaudio_handle = pa_simple_new(0, "vban", PA_STREAM_PLAYBACK, (output_name[0] == '\0') ? 0 : output_name, "", &ss, 0, &ba, &ret);
pulseaudio_backend->pulseaudio_handle = pa_simple_new(0, "vban", (direction == AUDIO_OUT) ? PA_STREAM_PLAYBACK : PA_STREAM_RECORD, (device_name[0] == '\0') ? 0 : device_name,
(direction == AUDIO_OUT) ? "playback": "record", &ss, 0, (direction == AUDIO_OUT) ? &ba : 0, &ret);
if (pulseaudio_backend->pulseaudio_handle == 0)
{
logger_log(LOG_FATAL, "pulseaudio_open: open error: %s", pa_strerror(ret));
@ -152,3 +155,30 @@ int pulseaudio_write(audio_backend_handle_t handle, char const* data, size_t siz
return (ret < 0) ? ret : size;
}
int pulseaudio_read(audio_backend_handle_t handle, char* data, size_t size)
{
int ret = 0;
int error;
struct pulseaudio_backend_t* const pulseaudio_backend = (struct pulseaudio_backend_t*)handle;
if ((handle == 0) || (data == 0))
{
logger_log(LOG_ERROR, "%s: handle or data pointer is null", __func__);
return -EINVAL;
}
if (pulseaudio_backend->pulseaudio_handle == 0)
{
logger_log(LOG_ERROR, "%s: device not open", __func__);
return -ENODEV;
}
ret = pa_simple_read(pulseaudio_backend->pulseaudio_handle, data, size, &error);
if (ret < 0)
{
logger_log(LOG_ERROR, "%s: pa_simple_read failed: %s", __func__, pa_strerror(error));
}
return (ret < 0) ? ret : size;
}

View File

@ -56,12 +56,14 @@ void usage()
printf("-i, --ipaddress=IP : MANDATORY. ipaddress to send stream to\n");
printf("-p, --port=PORT : MANDATORY. port to use\n");
printf("-s, --streamname=NAME : MANDATORY. streamname to use\n");
printf("-b, --backend=TYPE : audio backend to use. %s\n", audio_backend_get_help());
//XXX printf("-b, --backend=TYPE : audio backend to use. %s\n", audio_backend_get_help());
printf("-b, --backend=TYPE : TEMPORARY DISABLED. audio backend to use. Only alsa backend is working at this time\n");
printf("-d, --device=NAME : Audio device name. This is file name for file backend, server name for jack backend, device for alsa, stream_name for pulseaudio.\n");
printf("-r, --rate=VALUE : Audio device sample rate. default 44100\n");
printf("-n, --nbchannels=VALUE : Audio device number of channels. default 2\n");
printf("-f, --format=VALUE : Audio device sample format (see below). default is 16I (16bits integer)\n");
printf("-c, --channels=LIST : channels from the audio device to use. LIST is of form x,y,z,... default is to forward the stream as it is\n");
//XXX printf("-c, --channels=LIST : channels from the audio device to use. LIST is of form x,y,z,... default is to forward the stream as it is\n");
printf("-c, --channels=LIST : TEMPORARY DISABLED.\n");
printf("-l, --loglevel=LEVEL : Log level, from 0 (FATAL) to 4 (DEBUG). default is 1 (ERROR)\n");
printf("-h, --help : display this message\n\n");
@ -118,8 +120,8 @@ int get_options(struct config_t* config, int argc, char* const* argv)
strncpy(config->stream_name, optarg, VBAN_STREAM_NAME_SIZE);
break;
case 'b':
strncpy(config->audio.backend_name, optarg, AUDIO_BACKEND_NAME_SIZE);
/*XXX case 'b':
strncpy(config->audio.backend_name, optarg, AUDIO_BACKEND_NAME_SIZE);*/
case 'd':
strncpy(config->audio.device_name, optarg, AUDIO_DEVICE_NAME_SIZE);
@ -137,9 +139,9 @@ int get_options(struct config_t* config, int argc, char* const* argv)
config->stream.bit_fmt = stream_parse_bit_fmt(optarg);
break;
case 'c':
/*XXX case 'c':
ret = audio_parse_map_config(&config->map, optarg);
break;
break;*/
case 'l':
logger_set_output_level(atoi(optarg));

View File

@ -58,7 +58,8 @@ void usage()
printf("-s, --streamname=NAME : MANDATORY. streamname to play\n");
printf("-b, --backend=TYPE : audio backend to use. %s\n", audio_backend_get_help());
printf("-q, --quality=ID : network quality indicator from 0 (low latency) to 4. default is 1\n");
printf("-c, --channels=LIST : channels from the stream to use. LIST is of form x,y,z,... default is to forward the stream as it is\n");
//XXX printf("-c, --channels=LIST : channels from the stream to use. LIST is of form x,y,z,... default is to forward the stream as it is\n");
printf("-c, --channels=LIST : TEMPORARY DISABLED\n");
printf("-o, --output=NAME : DEPRECATED. please use -d\n");
printf("-d, --device=NAME : Audio device name. This is file name for file backend, server name for jack backend, device for alsa, stream_name for pulseaudio.\n");
printf("-l, --loglevel=LEVEL : Log level, from 0 (FATAL) to 4 (DEBUG). default is 1 (ERROR)\n");
@ -155,9 +156,9 @@ int get_options(struct config_t* config, int argc, char* const* argv)
quality = atoi(optarg);
break;
case 'c':
/*XXX case 'c':
ret = audio_parse_map_config(&config->map, optarg);
break;
break;*/
case 'o':
case 'd':