Ошибка сегментации (ядро сброшено) при использовании pulseaudio lib на c - PullRequest
1 голос
/ 05 февраля 2020

Я новичок в Stackoverflow и c и pulseaudio. Спасибо за помощь. Я получаю ошибку Segmentation fault (core dumped) в mainl oop пользовательского кода pulseaudiolib. Это займет от 1 до 30 секунд.

Я пытаюсь получить аудиоданные из пользовательского приемника

pacmd load-module module-null-sink sink_name=MySink
pacmd update-sink-proplist MySink device.description=MySink

pacmd load-module module-loopback sink=MySink

использовать его данные и передать его обратно в динамик.

Я довольно новичок в C и pulseaudio, поэтому я использовал do c и https://menno.io/posts/pulseaudio_monitoring/

Это мой код:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#include <pulse/context.h>
#include <pulse/def.h>
#include <pulse/format.h>
#include <pulse/introspect.h>
#include <pulse/stream.h>
#include <pulse/thread-mainloop.h>

const char * SINKNAME = "MySink";
const char * SPEAKNAME = "alsa_output.pci-0000_05_00.6.analog-stereo";
char found = 0;
const uint32_t RATE = 344;
pa_stream * gStream = NULL;

void stream_read_cb(pa_stream *stream, size_t length, void *index_incr){
    printf("in read\n");
    const void * samples[length];
    size_t * leng;
    (*leng) = length;
    printf("length : %d, %d\n",length,(*leng));
    int res = pa_stream_peek(stream, samples, leng);
    pa_stream_drop(stream);
    if(gStream != NULL){
        int result =  pa_stream_write( gStream, samples,length, NULL,0, PA_SEEK_RELATIVE);
    }
    printf("[");
    if (res == 0){
        for(int i = 0 ; i< length; i++){
            printf("%d,",samples[i]);
        }
    }
    printf("]\n");
}

void sink_info_cb(pa_context* context, const pa_sink_info *sink_info_p, int eol, void *userdata){

    printf( "in sinkinfo\n");
    const pa_sink_info* sink_info = sink_info_p;
    if(found !=1){
        printf( "index: %d\n", (*sink_info).index);
        printf("help\n");
        printf( "name: %s\n", (*sink_info).name);
        printf( "description: %s\n", (*sink_info).description);
        printf("searchName: %s\n",SINKNAME);
        if (strcmp((*sink_info).name, SINKNAME) == 0){
            found = 1;

            // Found the sink we want to monitor for peak levels.
            // Tell PA to call stream_read_cb with peak samples.
            printf( "setting up peak recording using: %s\n ", (*sink_info).monitor_source_name);
            pa_sample_spec *samplespec;
            (*samplespec).channels = 1;
            (*samplespec).format = PA_SAMPLE_U8;
            (*samplespec).rate = RATE;

            pa_stream * stream = pa_stream_new(context, "peak detect demo", samplespec, NULL);
            pa_stream_set_read_callback(stream,
                                        stream_read_cb,
                                        ( *sink_info).index);
            pa_stream_connect_record(stream,
                    (*sink_info).monitor_source_name,
                                     NULL,
                                     PA_STREAM_PEAK_DETECT);
            printf("settetd \n");
        }/*
        if((*sink_info).name[0] == 'a'){
            //printf( "setting up peak recording using: %s\n ", (*sink_info).monitor_source_name);
            //pa_sample_spec *samplespec;
            //  (*samplespec).channels = 1;
            //  (*samplespec).format = PA_SAMPLE_U8;
            //  (*samplespec).rate = RATE;
            printf("set gStream");
            //gStream = pa_stream_new(context, "peak detect demo", samplespec, NULL);
            //printf("gSteam setted\n");
        }*/

        printf("out sink\n");
    }
}

void context_notify_cb(pa_context *context, void *userdata){
    printf("in context\n");
    pa_context_state_t state = pa_context_get_state(context);
    if( state == PA_CONTEXT_READY){
        printf( "Pulseaudio connection ready...");
        // Connected to Pulseaudio. Now request that sink_info_cb
        // be called with information about the available sinks.
        pa_operation * o = pa_context_get_sink_info_list(context, sink_info_cb, userdata);
        pa_operation_unref(o);
    }
    else if( state == PA_CONTEXT_FAILED){
            printf( "Connection failed");
        }


    else if( state == PA_CONTEXT_TERMINATED){
        printf( "Connection terminated");
    }
    printf("out context\n");
}

void init(){
    // Wrap callback methods in appropriate ctypefunc instances so
    // that the Pulseaudio C API can call them
    printf("in init\n");
    pa_context_notify_cb_t _context_notify_cb;
    //context_notify_cb(context_notify_cb void ** userdata);
    pa_sink_info_cb_t(sink_info_cb);
    pa_stream_request_cb_t(stream_read_cb);


    // Create the mainloop thread and set our context_notify_cb
    // method to be called when there's updates relating to the
    // connection to Pulseaudio
    pa_threaded_mainloop* _mainloop = pa_threaded_mainloop_new();
    pa_mainloop_api* _mainloop_api = pa_threaded_mainloop_get_api(_mainloop);
    pa_context *context = pa_context_new(_mainloop_api, "peak_demo");
    pa_context_set_state_callback(context, context_notify_cb,NULL);
    pa_context_connect(context, NULL, 0, NULL);
    pa_threaded_mainloop_start(_mainloop);
    printf("out intit\n");
}

int main(int argc, char*argv[]) {
    init();
    printf("Hello World\n");
    while(1){
        ;
    }
    printf("end World\n");
    return 0;

}

если я попытаюсь раскомментировать

/*
        if((*sink_info).name[0] == 'a'){
            //printf( "setting up peak recording using: %s\n ", (*sink_info).monitor_source_name);
            //pa_sample_spec *samplespec;
            //  (*samplespec).channels = 1;
            //  (*samplespec).format = PA_SAMPLE_U8;
            //  (*samplespec).rate = RATE;
            printf("set gStream");
            //gStream = pa_stream_new(context, "peak detect demo", samplespec, NULL);
            //printf("gSteam setted\n");
        }
*/

ошибка снимков будет выглядеть следующим образом.

вывод:

...
in read
length : 1, 1
[-1261830080,]
in read
length : 6, 6
[-1246625728,-1017902384,0,0,-1017902304,591610535,]
in read
length : 1, 1
[-1259864000,]
in read
length : 6, 6
[-1227227072,-1017902384,0,0,-1017902304,591610535,]
in read
length : 1, 1
[-1255800768,]
in read
length : 6, 6
[-1234960320,-1017902384,0,0,-1017902304,591610535,]
in read
length : 7, 7
[-1249247168,-939474438,-1017902512,-1017902384,0,0,-1017902304,]
in read
length : 7, 7
[-1242693568,-939474438,-1017902464,-1017902336,0,0,-1017902256,]
Segmentation fault (core dumped)

вывод комментария:

in init
in context
out context
out intit
Hello World
in context
out context
in context
out context
in context
Pulseaudio connection ready...out context
in sinkinfo
index: 0
help
name: alsa_output.pci-0000_05_00.6.analog-stereo
description: Family 17h (Models 10h-1fh) HD Audio Controller Analog Stereo
searchName: MySink
set gStreamout sink
in sinkinfo
index: 1
help
name: MySink
description: MySink
searchName: MySink
setting up peak recording using: MySink.monitor
 settetd
Segmentation fault (core dumped)
...