UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
playback.cpp
Go to the documentation of this file.
1
5/*
6 * Copyright (c) 2022 CESNET, z. s. p. o.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, is permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * 3. Neither the name of CESNET nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
26 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
28 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#include "config_unix.h"
41#include "config_win32.h"
42#endif /* HAVE_CONFIG_H */
43
44#include <memory>
45#include <string_view>
46
47#include "debug.h"
48#include "module.h"
49#include "audio/audio_filter.h"
50#include "audio/types.h"
51#include "audio/audio_playback.h"
52#include "lib_common.h"
54#include "utils/misc.h"
55
56namespace{
57struct Playback_dev_deleter{ void operator()(state_audio_playback *p){ audio_playback_done(p); } };
58using Playback_dev_uniq = std::unique_ptr<state_audio_playback, Playback_dev_deleter>;
59}
60
63
65
66 int bps = 0;
67 int ch_count = 0;
68 int sample_rate = 0;
69
70 Playback_dev_uniq playback_dev;
71
72};
73
74static void usage(){
75 printf("Plays audio using an UltraGrid playback device:\n\n");
76 printf("playback usage:\n");
77 printf("\tplayback:<playback dev>:<dev config>\n\n");
78}
79
80static af_result_code parse_cfg(state_playback *s, std::string_view cfg){
81 auto tok = tokenize(cfg, ':');
82 if(tok.empty() || tok == "help"){
83 usage();
84 return AF_HELP_SHOWN;
85 }
86
87 auto dev = std::string(tok);
88 auto dev_cfg = std::string(tokenize(cfg, ':'));
89
90 int ret = audio_playback_init(dev.c_str(), dev_cfg.c_str(), out_ptr(s->playback_dev));
91
92 return ret == 0 ? AF_OK : AF_FAILURE;
93}
94
95static af_result_code init(struct module *parent, const char *cfg, void **state){
96 auto s = std::make_unique<state_playback>(parent);
97
98 auto ret = parse_cfg(s.get(), cfg);
99 if(ret == AF_OK)
100 *state = s.release();
101
102 return ret;
103};
104
106 int in_bps, int in_ch_count, int in_sample_rate)
107{
108 auto s = static_cast<state_playback *>(state);
109
110 s->bps = in_bps;
111 s->ch_count = in_ch_count;
112 s->sample_rate = in_sample_rate;
113
114 if (audio_playback_reconfigure(s->playback_dev.get(), s->bps * 8,
115 s->ch_count,
116 s->sample_rate) != TRUE) {
117 return AF_FAILURE;
118 }
119
120 return AF_OK;
121}
122
123static void done(void *state){
124 auto s = static_cast<state_playback *>(state);
125
126 delete s;
127}
128
129static void get_configured(void *state,
130 int *bps, int *ch_count, int *sample_rate)
131{
132 auto s = static_cast<state_playback *>(state);
133
134 if(bps) *bps = s->bps;
135 if(ch_count) *ch_count = s->ch_count;
136 if(sample_rate) *sample_rate = s->sample_rate;
137}
138
140 auto s = static_cast<state_playback *>(state);
141
142 struct message *msg;
143 while ((msg = check_message(s->mod.get()))) {
144 const char *text = ((msg_universal *) msg)->text;
145 if(parse_cfg(s, text) != AF_OK){
147 continue;
148 }
149
151 }
152
153 auto f = *frame;
154
155 if(f->bps != s->bps || f->ch_count != s->ch_count || f->sample_rate != s->sample_rate){
156 if(configure(state, f->bps, f->ch_count, f->sample_rate) != AF_OK){
157 return AF_MISCONFIGURED;
158 }
159 }
160
161 audio_playback_put_frame(s->playback_dev.get(), f);
162
163 return AF_OK;
164}
165
167 .name = "playback",
168 .init = init,
169 .done = done,
170 .configure = configure,
171 .get_configured_in = get_configured,
172 .get_configured_out = get_configured,
173 .filter = filter,
174};
175
void ** state
int int int sample_rate
struct video_frame * frame
This file contains definition of some common audio types.
#define AUDIO_FILTER_ABI_VERSION
af_result_code
@ AF_FAILURE
@ AF_MISCONFIGURED
@ AF_HELP_SHOWN
@ AF_OK
bool audio_playback_reconfigure(struct state_audio_playback *s, int quant_samples, int channels, int sample_rate)
int audio_playback_init(const char *device, const char *cfg, struct state_audio_playback **state)
void audio_playback_put_frame(struct state_audio_playback *s, const struct audio_frame *frame)
void audio_playback_done(struct state_audio_playback *s)
Definition misc.h:94
#define TRUE
@ MODULE_CLASS_DATA
Definition module.h:86
@ LIBRARY_CLASS_AUDIO_FILTER
Definition lib_common.h:85
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
Definition lib_common.h:144
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct message * check_message(struct module *mod)
#define RESPONSE_OK
Definition messaging.h:57
#define RESPONSE_BAD_REQUEST
Definition messaging.h:60
static af_result_code filter(void *state, struct audio_frame **frame)
Definition playback.cpp:139
static void usage()
Definition playback.cpp:74
static void get_configured(void *state, int *bps, int *ch_count, int *sample_rate)
Definition playback.cpp:129
static const struct audio_filter_info audio_filter_playback
Definition playback.cpp:166
static af_result_code init(struct module *parent, const char *cfg, void **state)
Definition playback.cpp:95
static af_result_code configure(void *state, int in_bps, int in_ch_count, int in_sample_rate)
Definition playback.cpp:105
static void done(void *state)
Definition playback.cpp:123
static af_result_code parse_cfg(state_playback *s, std::string_view cfg)
Definition playback.cpp:80
struct msghdr msg
const char * parent
Definition settings.cpp:198
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
struct used to comunicate with audio capture/playback device
Definition types.h:99
state_playback(struct module *mod)
Definition playback.cpp:62
module_raii mod
Definition playback.cpp:64
Playback_dev_uniq playback_dev
Definition playback.cpp:70