Уровни громкости в дБ для экспорта аудиофайла в Linux

Я хотел бы иметь возможность создать какой-то файл, в котором будут храниться уровни громкости аудиофайла. Я довольно гибок в этом вопросе, но примером может служить CSV, который показывает объем каждую секунду. Мне не нужно, чтобы это число было таким точным.

Есть ли у вас какие-нибудь предложения, как к этому подойти? Буду премного благодарен.


person hendr1x    schedule 28.04.2013    source источник
comment
Вы нашли решение?   -  person Andrey Volk    schedule 26.03.2014


Ответы (2)


Вы можете взять библиотеку BASS (бесплатно для некоммерческих целей) и использовать BASS_ChannelGetLevel ().

Вот код для получения уровней и вывода их в STDOUT:

#include <cstddef>
#include <stdio.h>
#include <stdlib.h>

#include "bass.h"

int main(int argc, char **argv)
{
    BASS_Init(0 /* "NO SOUND" device */, 44100, 0, 0, NULL);
    if ( argc == 3 )
    {
        int block = atoi( argv[2] ); // take levels every argv[2] ms
        if ( block < 20 )
            block = 20;

        HSTREAM chan = BASS_StreamCreateFile(FALSE, argv[1], 0, 0, BASS_STREAM_DECODE);
        if ( chan )
        {
            // BASS_ChannelGetLevel takes 20ms from the channel
            QWORD len = BASS_ChannelSeconds2Bytes(chan, (float)block / (float)1000 - (float)0.02); 

            char data[len];
            DWORD level, left, right;

            while ( -1 != (level = BASS_ChannelGetLevel(chan) ) ) // takes 20ms
            {
                left=LOWORD(level); // the left level
                right=HIWORD(level); // the right level
                printf("%i, %i\n", left, right);
                BASS_ChannelGetData(chan, data, len); // get data away from the channel
            }
            BASS_StreamFree( chan );
        }
    }

    BASS_Free();
    return 0;
}

Извлеките bass.h и libbass.so из архива bass24-linux.zip и создайте файл cpp с помощью:

g++ levels.cpp -o levels -lbass

Как выполнить: выравнивает имя файла в миллисекундах (минимум 20)

./levels 1.mp3 5000 >levels.txt

Вот файл levels.txt с уровнями, снимаемыми каждые 5 секунд (левый канал, правый канал):

1, 2
23235, 20363
22704, 20601
27203, 22476
10384, 12082
12059, 13387
9600, 10063
14590, 12261
16428, 14745
17569, 14723
29628, 27913
20799, 23554
24056, 20564
20344, 21242
21318, 22888
25389, 29050
27185, 23924
25469, 22540
28453, 29037
19669, 19797
16497, 16086
12081, 11843
20030, 20050
20512, 19537
19347, 14610
27673, 26563
26414, 24696
19775, 22869
24137, 25127
22093, 23184
26563, 24422
27718, 23791
24456, 26598
29353, 22647
562, 508

Уровень линейно изменяется от 0 (бесшумный) до 32768 (макс.).

Время для файла mp3 размером 6 МБ, период 100 мс:

# time ./levels 1.mp3 100 >levels.txt

real    0m0.981s
user    0m0.972s
sys     0m0.008s

Около секунды для создания файла levels.txt размером 22 Кб с периодом 100 мс.

person Andrey Volk    schedule 02.05.2013
comment
@ user1322158 Если у вас возникнут проблемы, свяжитесь со мной. - person Andrey Volk; 07.05.2013
comment
Я поместил bass.h, levels.cpp, and libbass.so в их собственный каталог и выполнил команду компиляции g++, но получил сообщение об ошибке: /usr/bin/ld: cannot find -lbass - person Xeoncross; 22.03.2014
comment
Я добавил -L ., чтобы указать g++, где найти libbass.so. Однако я все еще получаю / usr / bin / ld: пропуск несовместимого ./libbass.so при поиске -lbass - person Xeoncross; 22.03.2014
comment
Затем я добавил -m32 по умолчанию на 32-битную, так как я использую 64-битную ОС. Однако теперь он жалуется /usr/include/features.h:323:26: fatal error: bits/predefs.h: No such file or directory - person Xeoncross; 22.03.2014
comment
Я отказался от 32-битной libbass.so и вместо этого использовал версию из папки x64. Он скомпилирован отлично. Однако я пошел запустить его, и там написано ./levels: error while loading shared libraries: libbass.so: cannot open shared object file: No such file or directory - person Xeoncross; 22.03.2014
comment
Вероятно, вам нужно добавить -L./path/to/bass/lib в параметры компоновщика - person Andrey Volk; 22.03.2014
comment
Я сделал, как указано выше, но я все еще получаю сообщение об ошибке, когда пытаюсь запустить его. Я думаю, это как-то связано с LD_LIBRARY_PATH. - person Xeoncross; 22.03.2014
comment
попробуйте запустить export LD_LIBRARY_PATH="/path/to/bass/lib" перед запуском приложения - person Andrey Volk; 22.03.2014
comment
Сработало, хотя я добавил его вместо перезаписи `export LD_LIBRARY_PATH = $ LD_LIBRARY_PATH: / path / to / lib - person Xeoncross; 22.03.2014
comment
Можно ли добавить значение отметки времени, чтобы отметить время, когда была взята проба? - person Xeoncross; 22.03.2014
comment
Почему? Вы устанавливаете период. Таким образом, вы всегда знаете, из каких значений времени. Если вы получаете значения для каждых 20 мс, значит, у вас есть 0, 20, 40, 60, ... - person Andrey Volk; 26.03.2014

Псевдокод:

open input (audio) file
open output (data) file
for each one second chunk
   read samples for current chunk
   calculate RMS value (rms = sqrt(sum(x^2)/N))
   convert RMS value to dB (db = 20 * log10(rms))
   save dB value in output file
close input file
close output file
person Paul R    schedule 28.04.2013
comment
Спасибо, Пол, что уделили время, напечатав это. Вы можете объяснить, как я могу открыть / прочитать аудиоданные? Спасибо. - person hendr1x; 28.04.2013
comment
Существуют различные сторонние библиотеки для работы с аудиофайлами - выбор будет зависеть от вашей ОС / платформы / языка программирования и от того, с какими форматами аудиофайлов вам нужно работать. - person Paul R; 28.04.2013
comment
Я работаю над системой CentOS, я надеялся, что смогу создать файл через оболочку, но готов работать практически на любом языке (при условии, что мне не нужно слишком много учиться), формат аудиофайла не это вообще не имеет значения, я могу конвертировать в любой удобный формат. - person hendr1x; 28.04.2013
comment
Хорошо, я бы, наверное, начал с просмотра libsox - person Paul R; 28.04.2013
comment
Спасибо за предложение ... В настоящее время у меня есть следующая команда sox file.wav -r 1 file.dat, которая выводит что-то вроде ; Sample Rate 10 ; Channels 2 0 0.00085449219 -0.0007019043 0.1 0.01348877 -0.011260986 0.2 0.015930176 -0.013214111 0.3 0.014923096 -0.012390137. Не могли бы вы объяснить, что такое x и N (и если я использую правильные параметры для sox)? Благодаря тонну. - person hendr1x; 30.04.2013
comment
sox -r просто дает вам дамп образцов значений - вы можете прочитать их в другой программе, а затем выполнить обработку, как указано в моем ответе выше, хотя я бы предложил использовать libsox и просто написать одну программу, которая делает все - это будет более эффективно, чем преобразование данных в текст с последующей обработкой второй программой. - person Paul R; 30.04.2013