LINUX.ORG.RU

Sound auto-detect


0

0

Д.В.С.

Нужно писать звук, когда он поступает на звуковушку, тишину не писать. Это вообще реально?

Спасибо.

Написав велосипед на С, я поискал-таки слово "silence" в man sox.

Вот что я нашел:

silence above_periods [ duration threshold[ d | % ] [ below_periods duration threshold[ d | % ]]

Removes silence from the beginning or end of a sound file. Silence is anything below a specified threshold. When trimming silence from the beginning of a sound file, you specify a duration of audio that is above a given silence threshold before audio data is processed. You can also spec- ify the count of periods of none-silence you want to detect before processing audio data. Specify a period of 0 if you do not want to trim data from the front of the sound file. When optionally trimming silence form the end of a sound file, you specify the duration of audio that must be below a given threshold before stopping to process audio data. A count of periods that occur below the threshold may also be specified. If this options are not specified then data is not trimmed from the end of the audio file. If below_periods is negative, it is treated as a positive value and is also used to indicate the effect should restart processing as specified by the above_periods, making it suitable for remov- ing periods of silence in the middle of a sound file. Duration counts may be in the format of time, hh:mm:ss.frac, or in the exact count of samples. Threshold may be suffixed with d, or % to indicated the value is in decibels or a percentage of max value of the sample value. A value of '0%' will look for total silence.

lodin ★★★★
()
Ответ на: комментарий от lodin

У sox непонятно, что будет если файл целиком будет silence, этот ключ по идее служит для обрезания тишины в начале или конце файла. Да, непонятно как их загнать в трубу.

А на велосипед можно взглянуть?

Mousehouse
() автор топика
Ответ на: комментарий от Mousehouse

Вообще, некоторые эффекты работают в варианте command1 | sox - - effect ... | command2.

А вот глотать отрицательные периоды (как описано в мане) оно отказывается.

Велосипед по здравому размышлению признан недоделанным, но я его все-таки повешу.

lodin ★★★★
()
Ответ на: комментарий от Mousehouse

bash$ cat sndetect.c 
#include <stdlib.h>
#include <stdio.h>

/*
 *   read until the buffer is full
 *   the arguments are the same as in read()
 */

int read_fill (int fd, void * buffer, int buf_size) {
        int nbytes = 0;
        int ret = 0;

        /*
         *   try filling the rest of the buffer on every iteration
         *   INVARIANT: *buffer + buf_size = const
         */

        while (buf_size > 0) {
                ret = read (fd, buffer, buf_size);
                if (ret <= 0) break;

                nbytes += ret;
                buf_size -= ret;
                buffer = ((char *)buffer) + ret;
        };

        /* if there's an error, return it unchanged */
        if (ret < 0)
                return ret;
        else 
                return nbytes;
};

int main () {

        /*
         *  This is the buffer to read stdin into.
         */
        short *buf;
        int buf_size=22500; /* for 1 second of silence */

        /*
         *  Treshold
         */
        int trhold = 100;

        /* introduce a state machine: 
        *  0 = there is no sound
        *  1 = there is some sound in the input
        *  (0, sound) -> 1   and write buffer to stdout
        *  (0, nosound) -> 0
        *  (1, sound) -> 1   and write buffer to stdout 
        *  (1, nosound) -> 0 and write buffer to stdout, 
                                 to retain a frame of silence between fragments
        */
        int state = 0; 
        int sound = 0;

        /* numberr of bytes read */
        int nbytes = 0;  

        /* allocate the input buffer */
        buf = malloc (buf_size * sizeof (short));
        if (buf == NULL) {
                fprintf (stderr, "Not enough memory to fit the buffer\n");
                exit (1);
        };

        /* read stdin, repeatedly, skipping frames which are below treshold */
        while ((nbytes = read_fill (0, buf, buf_size * sizeof (short)) ) >0 ) {
                int i = nbytes / sizeof (short);

                /* search for signal */
                sound = 0;
                while (i-->0) {
                        if ( (buf[i] > trhold) || (buf[i] < -trhold) ) {
                                sound = 1;
                                break;
                        };
                };

                fprintf (stderr, "\tread %u bytes, state=%u, sound=%u\n", nbytes, state, sound);

                /* implement state machine */
                if (sound || state) {
                        write (1, buf, nbytes);
                };

                state = sound;
        };

        return 0;
};

      

lodin ★★★★
()
Ответ на: комментарий от lodin

Usage

К сожалению, все захардкожено пока что. Кроме того, прога чувствительна к щелчкам -- можно в принципе переписать, чтобы мощность считала... но лень.

buf_size -- это сколько читать short-ов. trhold -- это порог, который не должны превышать все short-ы в пределах фрагмента.

Используется так:

bash$ rec -t raw -sw -r 22500 - | ./sndetect > output.raw

bash$ play -t raw -sw -r 22500 -v 50 output.raw

Опять же, можно использовать sox для конвертирования в нормальный формат, огг например.

lodin ★★★★
()
Ответ на: Usage от lodin

Большой сеньк, поковыряем...

Mousehouse
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.