C 如何使用gstreamer解析音频原始数据记录器?
我正在编写一个C应用程序,它使用gstreamer从麦克风录制音频。 我希望能够解析该音频并显示该音频的可视化 我有以下代码:C 如何使用gstreamer解析音频原始数据记录器?,c,gstreamer,C,Gstreamer,我正在编写一个C应用程序,它使用gstreamer从麦克风录制音频。 我希望能够解析该音频并显示该音频的可视化 我有以下代码: #include <gst/gst.h> #include <glib.h> static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; sw
#include <gst/gst.h>
#include <glib.h>
static gboolean
bus_call (GstBus *bus,
GstMessage *msg,
gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *error;
gst_message_parse_error (msg, &error, &debug);
g_free (debug);
g_printerr ("Error: %s\n", error->message);
g_error_free (error);
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
void create_loop()
{
GMainLoop *loop;
GstElement *pipeline, *source, *sink;
GstBus *bus;
guint bus_watch_id;
/* Initialisation */
loop = g_main_loop_new (NULL, FALSE);
/* Create gstreamer elements */
pipeline = gst_pipeline_new ("audio-player");
source = gst_element_factory_make ("alsasrc", "alsa-source");
sink = gst_element_factory_make ("autoaudiosink", "audio-output");
if (!pipeline || !source || !sink) {
g_printerr ("One element could not be created. Exiting.\n");
return;
}
g_object_set (G_OBJECT(source),"device","hw:3,0",NULL);
/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
gst_bin_add_many (GST_BIN (pipeline),
source, sink, NULL);
gst_element_link (source, sink);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Iterate */
g_print ("Running...\n");
g_main_loop_run (loop);
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
g_source_remove (bus_watch_id);
g_main_loop_unref (loop);
}
int main(int argc, char** argv) {
gst_init(&argc,&argv);
create_loop();
return 0;
}
#包括
#包括
静态gboolean
总线呼叫(GstBus*总线,
GstMessage*msg,
gpointer数据)
{
GMainLoop*循环=(GMainLoop*)数据;
开关(GST\信息\类型(msg)){
案例GST\信息\ EOS:
g_打印(“流结束\n”);
g_主循环退出(循环);
打破
案例GST\u消息\u错误:{
gchar*调试;
GError*错误;
gst\消息\解析\错误(消息、错误和调试);
g_自由(调试);
g_printerr(“错误:%s\n”,错误->消息);
g_无错误(错误);
g_主循环退出(循环);
打破
}
违约:
打破
}
返回TRUE;
}
void create_loop()
{
GMainLoop*循环;
GstElement*管道、*源、*汇;
GstBus*总线;
吉尼特巴士公司;
/*初始化*/
loop=g_main_loop_new(NULL,FALSE);
/*创建gstreamer元素*/
管道=gst_管道_新(“音频播放器”);
来源=商品及服务税元素工厂制造(“alsasrc”、“alsa来源”);
接收器=gst元件工厂制造(“自动音频接收器”、“音频输出”);
如果(!管道| | |!源| |!接收器){
g_printerr(“无法创建一个元素。正在退出。\n”);
返回;
}
g_对象集(g_对象(源),“设备”,“硬件:3,0”,空);
/*我们添加了一个消息处理程序*/
总线=gst_管道_获取_总线(gst_管道(管道));
bus_watch_id=gst_bus_add_watch(总线、总线调用、环路);
商品及服务税(巴士);
gst_bin_add_many(gst_bin(管道),
源、汇、空);
gst_元素_链接(源、汇);
gst元素设置状态(管道、gst状态);
/*迭代*/
g_打印(“运行…\n”);
g_主循环运行(循环);
/*离开主回路,好好清理*/
g_print(“返回,停止播放”);
gst\元素\集合\状态(管道,gst\状态\空);
g_print(“删除管道”);
gst_对象_unref(gst_对象(管道));
g_源_移除(总线_监视_id);
g_主回路_unref(回路);
}
int main(int argc,字符**argv){
gst_init(&argc,&argv);
创建_循环();
返回0;
}
正如您在我的代码中看到的,我创建了一个alsasrc和autoaudiosink。我测试过了,我可以
仔细听那个设备
<>我如何在中间写一些东西来解析数据以便创建可视化?< /P>
非常感谢您提供有关此问题的任何信息。元素允许您从管道中获取数据
您有三种选择:
- 拉动:启动管道,然后使用
- 信号推送:启用
信号发射,并订阅该信号新样本
- 使用回调推送:在
新样本上注册回调
autoaudiosink
替换为appsink
,注册回调并在其中处理数据
您可以阅读一些关于appsrc
和appsink
的内容。元素允许您从管道中获取数据
您有三种选择:
- 拉动:启动管道,然后使用
- 信号推送:启用
信号发射,并订阅该信号新样本
- 使用回调推送:在
新样本上注册回调
autoaudiosink
替换为appsink
,注册回调并在其中处理数据
您可以在中阅读一些关于appsrc
和appsink
的内容。您需要为您的gsteamer应用程序创建一个“插件”或pad。
关于如何创建焊盘,有完整的说明:
在大多数情况下,您需要使用gobject创建一个类
以下是方法:
你至少需要:
/* Definition of structure storing data for this element. */
typedef struct _GstMyFilter {
GstElement element;
GstPad *sinkpad, *srcpad;
gboolean silent;
} GstMyFilter;
static GstStaticPadTemplate sink_factory =
GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("ANY")
);
//... likewise for your src
static void
gst_my_filter_class_init (GstMyFilterClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
//...
gst_element_class_set_static_metadata (element_klass,
"An example plugin",
"Example/FirstExample",
"Shows the basic structure of a plugin",
"your name <your.name@your.isp>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
}
你的魔法是由链条操纵的
static GstFlowReturn
gst_my_filter_chain (GstPad *pad,
GstObject *parent,
GstBuffer *buf)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
if (!filter->silent)
g_print ("Have data of size %" G_GSIZE_FORMAT" bytes!\n",
gst_buffer_get_size (buf));
return gst_pad_push (filter->srcpad, buf);
}
static gboolean
gst_my_filter_sink_event (GstPad *pad,
GstObject *parent,
GstEvent *event)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
/* we should handle the format here */
break;
case GST_EVENT_EOS:
/* end-of-stream, we should close down all stream leftovers here */
gst_my_filter_stop_processing (filter);
break;
default:
break;
}
return gst_pad_event_default (pad, parent, event);
}
static GstFlowReturn
gst_my_filter_chain (GstPad *pad,
GstObject *parent,
GstBuffer *buf)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
GstBuffer *outbuf;
outbuf = gst_my_filter_process_data (filter, buf);
gst_buffer_unref (buf);
if (!outbuf) {
/* something went wrong - signal an error */
GST_ELEMENT_ERROR (GST_ELEMENT (filter), STREAM, FAILED, (NULL), (NULL));
return GST_FLOW_ERROR;
}
return gst_pad_push (filter->srcpad, outbuf);
}
用例:
//... your code and elements init...
//Creating your filter
filter = gst_element_factory_make ("my_filter", "my_filter");
//Adding it
gst_bin_add_many (GST_BIN (pipeline), source, filter, sink, NULL);
//Linking it
if (!gst_element_link_many (source, filter, sink, NULL)) {
g_print ("Failed to link one or more elements!\n");
return -1;
}
//... here the rest of your code
奖励*有一个简单的例子:您需要为您的gsteamer应用程序创建一个“插件”或pad。
关于如何创建焊盘,有完整的说明:
在大多数情况下,您需要使用gobject创建一个类
以下是方法:
你至少需要:
/* Definition of structure storing data for this element. */
typedef struct _GstMyFilter {
GstElement element;
GstPad *sinkpad, *srcpad;
gboolean silent;
} GstMyFilter;
static GstStaticPadTemplate sink_factory =
GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("ANY")
);
//... likewise for your src
static void
gst_my_filter_class_init (GstMyFilterClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
//...
gst_element_class_set_static_metadata (element_klass,
"An example plugin",
"Example/FirstExample",
"Shows the basic structure of a plugin",
"your name <your.name@your.isp>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
}
你的魔法是由链条操纵的
static GstFlowReturn
gst_my_filter_chain (GstPad *pad,
GstObject *parent,
GstBuffer *buf)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
if (!filter->silent)
g_print ("Have data of size %" G_GSIZE_FORMAT" bytes!\n",
gst_buffer_get_size (buf));
return gst_pad_push (filter->srcpad, buf);
}
static gboolean
gst_my_filter_sink_event (GstPad *pad,
GstObject *parent,
GstEvent *event)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
/* we should handle the format here */
break;
case GST_EVENT_EOS:
/* end-of-stream, we should close down all stream leftovers here */
gst_my_filter_stop_processing (filter);
break;
default:
break;
}
return gst_pad_event_default (pad, parent, event);
}
static GstFlowReturn
gst_my_filter_chain (GstPad *pad,
GstObject *parent,
GstBuffer *buf)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
GstBuffer *outbuf;
outbuf = gst_my_filter_process_data (filter, buf);
gst_buffer_unref (buf);
if (!outbuf) {
/* something went wrong - signal an error */
GST_ELEMENT_ERROR (GST_ELEMENT (filter), STREAM, FAILED, (NULL), (NULL));
return GST_FLOW_ERROR;
}
return gst_pad_push (filter->srcpad, outbuf);
}
用例:
//... your code and elements init...
//Creating your filter
filter = gst_element_factory_make ("my_filter", "my_filter");
//Adding it
gst_bin_add_many (GST_BIN (pipeline), source, filter, sink, NULL);
//Linking it
if (!gst_element_link_many (source, filter, sink, NULL)) {
g_print ("Failed to link one or more elements!\n");
return -1;
}
//... here the rest of your code
奖金*有一个简单的例子: