FFmpeg
Loading...
Searching...
No Matches
af_asr.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Paul B Mahol
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <pocketsphinx/pocketsphinx.h>
22
23#include "libavutil/avstring.h"
25#include "libavutil/mem.h"
26#include "libavutil/opt.h"
27#include "audio.h"
28#include "avfilter.h"
29#include "filters.h"
30#include "formats.h"
31
32typedef struct ASRContext {
33 const AVClass *class;
34
35 int rate;
36 char *hmm;
37 char *dict;
38 char *lm;
39 char *lmctl;
40 char *lmname;
41 char *logfn;
42
43 ps_decoder_t *ps;
44 cmd_ln_t *config;
45
48
49#define OFFSET(x) offsetof(ASRContext, x)
50#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
51static const AVOption asr_options[] = {
52 { "rate", "set sampling rate", OFFSET(rate), AV_OPT_TYPE_INT, {.i64=16000}, 0, INT_MAX, .flags = FLAGS },
53 { "hmm", "set directory containing acoustic model files", OFFSET(hmm), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
54 { "dict", "set pronunciation dictionary", OFFSET(dict), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
55 { "lm", "set language model file", OFFSET(lm), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
56 { "lmctl", "set language model set", OFFSET(lmctl), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
57 { "lmname","set which language model to use", OFFSET(lmname), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
58 { "logfn", "set output for log messages", OFFSET(logfn), AV_OPT_TYPE_STRING, {.str="/dev/null"}, .flags = FLAGS },
59 { NULL }
60};
61
63
64static int filter_frame(AVFilterLink *inlink, AVFrame *in)
65{
66 AVFilterContext *ctx = inlink->dst;
68 ASRContext *s = ctx->priv;
69 int have_speech;
70 const char *speech;
71
72 ps_process_raw(s->ps, (const int16_t *)in->data[0], in->nb_samples, 0, 0);
73 have_speech = ps_get_in_speech(s->ps);
74 if (have_speech && !s->utt_started)
75 s->utt_started = 1;
76 if (!have_speech && s->utt_started) {
77 ps_end_utt(s->ps);
78 speech = ps_get_hyp(s->ps, NULL);
79 if (speech != NULL)
80 av_dict_set(metadata, "lavfi.asr.text", speech, 0);
81 ps_start_utt(s->ps);
82 s->utt_started = 0;
83 }
84
85 return ff_filter_frame(ctx->outputs[0], in);
86}
87
88static int config_input(AVFilterLink *inlink)
89{
90 AVFilterContext *ctx = inlink->dst;
91 ASRContext *s = ctx->priv;
92
93 ps_start_utt(s->ps);
94
95 return 0;
96}
97
99{
100 ASRContext *s = ctx->priv;
101 const float frate = s->rate;
102 char *rate = av_asprintf("%f", frate);
103 const char *argv[] = { "-logfn", s->logfn,
104 "-hmm", s->hmm,
105 "-lm", s->lm,
106 "-lmctl", s->lmctl,
107 "-lmname", s->lmname,
108 "-dict", s->dict,
109 "-samprate", rate,
110 NULL };
111
112 s->config = cmd_ln_parse_r(NULL, ps_args(), 14, (char **)argv, 0);
113 av_free(rate);
114 if (!s->config)
115 return AVERROR(ENOMEM);
116
117 ps_default_search_args(s->config);
118 s->ps = ps_init(s->config);
119 if (!s->ps)
120 return AVERROR(ENOMEM);
121
122 return 0;
123}
124
126 AVFilterFormatsConfig **cfg_in,
127 AVFilterFormatsConfig **cfg_out)
128{
129 static const enum AVSampleFormat formats[] = {
132 };
133 static const AVChannelLayout layouts[] = {
135 { .nb_channels = 0 },
136 };
137
138 const ASRContext *s = ctx->priv;
139 int sample_rates[] = { s->rate, -1 };
140 int ret;
141
142 ret = ff_set_sample_formats_from_list2(ctx, cfg_in, cfg_out, formats);
143 if (ret < 0)
144 return ret;
145
147 if (ret < 0)
148 return ret;
149
151 if (ret < 0)
152 return ret;
153
154 return 0;
155}
156
158{
159 ASRContext *s = ctx->priv;
160
161 ps_free(s->ps);
162 s->ps = NULL;
163 cmd_ln_free_r(s->config);
164 s->config = NULL;
165}
166
167static const AVFilterPad asr_inputs[] = {
168 {
169 .name = "default",
170 .type = AVMEDIA_TYPE_AUDIO,
171 .filter_frame = filter_frame,
172 .config_props = config_input,
173 },
174};
175
177 .p.name = "asr",
178 .p.description = NULL_IF_CONFIG_SMALL("Automatic Speech Recognition."),
179 .p.priv_class = &asr_class,
181 .priv_size = sizeof(ASRContext),
182 .init = asr_init,
187};
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition aeval.c:246
static int config_input(AVFilterLink *inlink)
static const AVFilterPad asr_inputs[]
Definition af_asr.c:167
static int config_input(AVFilterLink *inlink)
Definition af_asr.c:88
const FFFilter ff_af_asr
Definition af_asr.c:176
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition af_asr.c:64
static av_cold int asr_init(AVFilterContext *ctx)
Definition af_asr.c:98
static const AVOption asr_options[]
Definition af_asr.c:51
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition af_asr.c:125
static av_cold void asr_uninit(AVFilterContext *ctx)
Definition af_asr.c:157
#define OFFSET(x)
Definition af_asr.c:49
static AVFormatContext * ctx
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
Definition audio.c:34
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
char * av_asprintf(const char *fmt,...)
Definition avstring.c:115
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
#define FLAGS
Definition cmdutils.c:598
#define NULL
Definition coverity.c:32
static const int sample_rates[]
Definition dcaenc.h:34
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *samplerates)
Definition formats.c:1050
int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const AVChannelLayout *fmts)
Definition formats.c:1026
int ff_set_sample_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const enum AVSampleFormat *fmts)
Definition formats.c:1154
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition avfilter.h:182
#define AV_CHANNEL_LAYOUT_MONO
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AVERROR(e)
Definition error.h:45
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
#define FILTER_QUERY_FUNC2(func)
Definition filters.h:241
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
Memory handling functions.
enum MovChannelLayoutTag * layouts
Definition mov_chan.c:335
AVOptions.
formats
Definition signature.h:47
char * lmname
Definition af_asr.c:40
char * dict
Definition af_asr.c:37
char * lmctl
Definition af_asr.c:39
int rate
Definition af_asr.c:35
int utt_started
Definition af_asr.c:46
char * lm
Definition af_asr.c:38
char * hmm
Definition af_asr.c:36
cmd_ln_t * config
Definition af_asr.c:44
ps_decoder_t * ps
Definition af_asr.c:43
char * logfn
Definition af_asr.c:41
An AVChannelLayout holds information about the channel layout of audio data.
Describe the class of an AVClass context structure.
Definition log.h:76
An instance of a filter.
Definition avfilter.h:273
Lists of formats / etc.
Definition avfilter.h:120
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int nb_samples
number of audio samples (per channel) described by this frame
Definition frame.h:552
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
AVDictionary * metadata
metadata.
Definition frame.h:750
AVOption.
Definition opt.h:428
#define av_free(p)