gpt4 book ai didi

c - 使用 GStreamer 播放原始 PCM 数据

转载 作者:行者123 更新时间:2023-11-30 16:54:07 24 4
gpt4 key购买 nike

好吧,我在下面编写了一些代码,这些代码应该打开音频输出设备,每当实际的 PCM 数据可用时,我都会调用 Sound_WriteFrame() 并堆积更多要播放的数据。

数据是原始数据,没有 header ,因此当我调用 Sound_Open() 时,我传递此信息以使 GStreamer 知道将到达什么类型的数据。

这段代码不起作用 - 坦率地说,我不知道我在做什么,我发现 GStreamer 有点难以使用,我希望最终能够改变。

我正在使用 GStreamer 1.0。感谢帮助。

#include <gstreamer-1.0/gst/gst.h>
#include <gstreamer-1.0/gst/gstelement.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>

typedef struct _sound_t {
GstElement *source, *sink, *pipeline;
GMemoryInputStream *giostream;
GstPad *sourcepad;
GstCaps *gcaps;
int bDeviceOpen;
} SOUND_CTX;

int Sound_Close(SOUND_CTX *p){
printf("Closing\n");
gst_element_set_state(p->pipeline, GST_STATE_NULL);
return 1;
}

void Sound_SetState(SOUND_CTX *p, GstState state){
GstStateChangeReturn r = gst_element_set_state(p->pipeline, state);
switch(r){
case GST_STATE_CHANGE_FAILURE: printf("GST_STATE_CHANGE_FAILURE\n"); break;
case GST_STATE_CHANGE_SUCCESS: printf("GST_STATE_CHANGE_SUCCESS\n"); break;
case GST_STATE_CHANGE_ASYNC: printf("GST_STATE_CHANGE_ASYNC\n"); break;
case GST_STATE_CHANGE_NO_PREROLL: printf("GST_STATE_CHANGE_NO_PREROLL\n"); break;
default: printf("Unknown state\n"); break;
}
return;
}

int Sound_Open(SOUND_CTX *p, int nSamplesPerSec, int nChannels){

p->source = gst_element_factory_make("giostreamsrc", "source");
p->giostream = G_MEMORY_INPUT_STREAM(g_memory_input_stream_new());
g_object_set(G_OBJECT(p->source), "stream", G_INPUT_STREAM(p->giostream), NULL);
p->sourcepad = gst_element_get_static_pad(p->source, "src");

p->gcaps = gst_caps_new_simple(
"audio/x-raw",
"rate", G_TYPE_INT, nSamplesPerSec,
"channels", G_TYPE_INT, nChannels,
"width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"signed", G_TYPE_BOOLEAN, TRUE,
NULL
);

gst_pad_set_caps(p->sourcepad, p->gcaps);
gst_object_unref(p->sourcepad);

p->sink = gst_element_factory_make("alsasink", "sink");
p->pipeline = gst_pipeline_new("pipeline_name");
gst_bin_add_many(GST_BIN(p->pipeline), p->source, p->sink, NULL);
gst_element_link_many(p->source, p->sink, NULL);

Sound_SetState(p, GST_STATE_PLAYING);

return 1;
}

int Sound_WriteFrame(SOUND_CTX *p, void *lpData, unsigned int size){
g_memory_input_stream_add_data(
G_MEMORY_INPUT_STREAM(p->giostream),
lpData, size, NULL
);
return 0;
}

int timer_callback(const void *data){
g_main_loop_quit((GMainLoop *)data);
return FALSE;
}



int main(int argc, char *argv[]){
gst_init(&argc, &argv);
GMainLoop *loop = NULL;
SOUND_CTX a;
memset(&a, 0x00, sizeof(SOUND_CTX));
if(Sound_Open(&a, 44100, 2)){
FILE *handle;
unsigned char tmp[4096];
if((handle = fopen("test.pcm", "rb")) != NULL){
while(fread(tmp, 1, sizeof(tmp), handle) == sizeof(tmp)){
Sound_WriteFrame(&a, tmp, sizeof(tmp));
}
fclose(handle);
}
}

loop = g_main_loop_new(NULL, FALSE);
g_timeout_add(5500, (GSourceFunc)timer_callback, loop);
g_main_loop_run(loop);
Sound_Close(&a);
g_main_loop_unref(loop);

return 0;
}

好的,这是更新的源,但是扬声器没有声音

#include <gstreamer-1.0/gst/gst.h>
#include <gstreamer-1.0/gst/gstelement.h>
#include <gstreamer-1.0/gst/app/gstappsrc.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>

typedef struct _sound_t {
GstElement *sink, *pipeline;
GstAppSrc *src;
GstCaps *pcm_caps;
} SOUND_CTX;

int Sound_Close(SOUND_CTX *p){
printf("Closing\n");
gst_element_set_state(p->pipeline, GST_STATE_NULL);
return 1;
}

void Sound_SetState(SOUND_CTX *p, GstState state){
GstStateChangeReturn r = gst_element_set_state(p->pipeline, state);
switch(r){
case GST_STATE_CHANGE_FAILURE: printf("GST_STATE_CHANGE_FAILURE\n"); break;
case GST_STATE_CHANGE_SUCCESS: printf("GST_STATE_CHANGE_SUCCESS\n"); break;
case GST_STATE_CHANGE_ASYNC: printf("GST_STATE_CHANGE_ASYNC\n"); break;
case GST_STATE_CHANGE_NO_PREROLL: printf("GST_STATE_CHANGE_NO_PREROLL\n"); break;
default: printf("Unknown state\n"); break;
}
return;
}

int Sound_Open(SOUND_CTX *p, int nSamplesPerSec, int nChannels){

p->pipeline = gst_pipeline_new("pipeline_name");
p->sink = gst_element_factory_make("alsasink", "sink");

p->src = (GstAppSrc*) gst_element_factory_make("appsrc", "source");
gst_app_src_set_stream_type(p->src, GST_APP_STREAM_TYPE_STREAM);

// I am hardcoding the format, channels, and rate for now
p->pcm_caps = gst_caps_from_string("audio/x-raw,format=S16LE,rate=44100,channels=2");
gst_app_src_set_caps(p->src, p->pcm_caps);

gst_bin_add_many(GST_BIN(p->pipeline), (GstElement*)p->src, p->sink, NULL);
gst_element_link_many((GstElement*)p->src, p->sink, NULL);

Sound_SetState(p, GST_STATE_PLAYING);

return 1;
}

int Sound_WriteFrame(SOUND_CTX *p, void *lpData, unsigned int size){
GstBuffer *buf = NULL;
void *lpHeapData = NULL;
if((lpHeapData = g_malloc(size)) == NULL) return 0;
memcpy(lpHeapData, lpData, size);
buf = gst_buffer_new_wrapped(lpHeapData, size);
if(buf == NULL){
g_free(lpHeapData);
return 0;
}
gst_app_src_push_buffer(p->src, buf);
return 0;
}

int timer_callback(const void *data){
g_main_loop_quit((GMainLoop *)data);
return FALSE;
}



int main(int argc, char *argv[]){
gst_init(&argc, &argv);
GMainLoop *loop = NULL;
SOUND_CTX a;
memset(&a, 0x00, sizeof(SOUND_CTX));
if(Sound_Open(&a, 44100, 2)){
FILE *handle;
unsigned char tmp[4096];
if((handle = fopen("test.pcm", "rb")) != NULL){
while(fread(tmp, 1, sizeof(tmp), handle) == sizeof(tmp)){
Sound_WriteFrame(&a, tmp, sizeof(tmp));
}
fclose(handle);
}
}

loop = g_main_loop_new(NULL, FALSE);
g_timeout_add(5500, (GSourceFunc)timer_callback, loop);
g_main_loop_run(loop);
Sound_Close(&a);
g_main_loop_unref(loop);

return 0;
}

最佳答案

您在类似于 GStreamer 1.0 代码的内容中使用 GStreamer 0.10 Caps 字段。为了您的兴趣,宽度/深度/符号已被称为格式的单个字段取代。请参阅文档了解完整列表,大写的名称与枚举相同,但没有命名空间 GST_AUDIO_FORMAT_。

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstaudio.html#GstAudioFormat

关于c - 使用 GStreamer 播放原始 PCM 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40640414/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com