M
M
Michael742016-11-02 15:50:53
PHP
Michael74, 2016-11-02 15:50:53

Processing an audio stream and getting the signal level in decibels?

The task is to receive a stream from the equipment (for example, using ffmpeg) and display signal level values ​​in decibels in the user interface (browser).
Faced a problem on the client (browser + Web audio api), when trying to display 32 signal strength indicators, the browser crashed.
We came to the conclusion that it is necessary to calculate decibels on the server side and transfer these values ​​in RealTime to the client browser.
Is there anyone out there who can suggest a possible solution to this problem.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Savostin, 2016-11-03
@savostin

Here, on my knee in C , I stole a code that takes a signal from STDIN, outputs its level to STDERR and sends it to STDOUT:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <pulse/simple.h>
#include <pulse/error.h>
#include <pulse/volume.h>
#include <pulse/gccmacro.h>

#define BUFSIZE 1024

/* A simple routine calling UNIX write() in a loop */
static ssize_t loop_write(int fd, const void*data, size_t size) {
    ssize_t ret = 0;

    while (size > 0) {
        ssize_t r;

        if ((r = write(fd, data, size)) < 0)
            return r;

        if (r == 0)
            break;

        ret += r;
        data = (const uint8_t*) data + r;
        size -= (size_t) r;
    }

    return ret;
}

int main(int argc, char*argv[]) {
    /* The sample type to use */
    static const pa_sample_spec ss = {
        .format = PA_SAMPLE_S16LE,
        .rate = 44100,
        .channels = 2
    };
    pa_simple *s = NULL;
    int ret = 1;
    int error;

    /* Create the recording stream */
    if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
        fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
        goto finish;
    }

    for (;;) {
        uint8_t buf[BUFSIZE];

        /* Record some data ... */
        if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
            fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));
            goto finish;
        }

pa_cvolume pv = {};

pa_volume_t tt = pa_cvolume_avg(&pv);
fprintf(stderr, "%d\n", pv.values[0]);

        /* And write it to STDOUT */
        if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) {
            fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));
            goto finish;
        }
    }

    ret = 0;

finish:

    if (s)
        pa_simple_free(s);

    return ret;
}

Didn't test.
Decibels need to be calculated, with channels to be smarter, well, finish it off.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question