Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
SHAREN
0 / 0 / 0
Регистрация: 03.05.2016
Сообщений: 13
#1

Как взять громкость звукового файла в определенный момент времени? - C++

03.05.2016, 22:47. Просмотров 557. Ответов 22
Метки нет (Все метки)

Хочу сделать простую программку которая будет выводить 2 значения. 1 - громкость, 2 - тик
пример^
0.56 00000
0.47 00001
0.32 00002
0.39 00003
...
0.96 04324
0.88 04325

К сожалению я даже не новичок, а начинающий в с++, более менее умею только плагины на SourcePawn писать для CS.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.05.2016, 22:47     Как взять громкость звукового файла в определенный момент времени?
Посмотрите здесь:
C++ Определение времени подачи звукового сигнала
C++ Работа со звуком (как звуковые спектры определённого звукового файла записать цифрами в массив)
Как из FB2 файла взять картинку C++
Получение информации о частоте и длительности из звукового файла. C++
C++ Как взять данные из файла и сохранить в файл?
C++ Как создать калькулятор, и взять из внешнего файла значения
C++ Послать сообщение окну в указанный момент времени
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
SHAREN
0 / 0 / 0
Регистрация: 03.05.2016
Сообщений: 13
10.05.2016, 22:57  [ТС]     Как взять громкость звукового файла в определенный момент времени? #16
Нашел готовый код http://hamelot.io/other/output-spect...-bass-library/

P.S. а у меня в итоге получилось так
C++
1
2
3
4
5
6
7
8
9
10
11
12
if (BASS_Init(-1,44100,0,0,0)) {
    DWORD channel = BASS_StreamCreateFile(false,"D:/banana.mp3",0,0,0);         // BASS_STREAM_DECODE
    if (channel!=0) {
        cout << channel << endl;
        BASS_ChannelPlay(channel, true);
        float fft[512];
        BASS_ChannelGetData(channel,fft,BASS_DATA_FFT1024);
        for (int a=0; a<512; a++)
            printf("%d: %f\n",a,fft[a]);
        printf("BASS_ErrorCode %i \n", BASS_ErrorGetCode());
    } else printf("BASS_StreamCreateFile ERROR - BASS_ErrorCode %i \n",BASS_ErrorGetCode());
} else printf("Init ERROR - BASS_ErrorCode %i \n",BASS_ErrorGetCode());
почему-то массив заполнялся нулями.
nmcf
5273 / 4593 / 1538
Регистрация: 14.04.2014
Сообщений: 18,243
10.05.2016, 23:03     Как взять громкость звукового файла в определенный момент времени? #17
Звук воспроизводится? Может, там указатель сдвигается как у файлов? Попробуй закомментировать пятую строку.
SHAREN
0 / 0 / 0
Регистрация: 03.05.2016
Сообщений: 13
10.05.2016, 23:09  [ТС]     Как взять громкость звукового файла в определенный момент времени? #18
Звук играет, без неё тоже нулями заполняется и с флагом BASS_STREAM_DECODE тоже в BASS_StreamCreateFile.
В общем код по ссылке рабочий, записывает в файл все как надо.
Но за помощь и уделённое время большое спасибо.
nmcf
5273 / 4593 / 1538
Регистрация: 14.04.2014
Сообщений: 18,243
10.05.2016, 23:26     Как взять громкость звукового файла в определенный момент времени? #19
Так оно заработало?
SHAREN
0 / 0 / 0
Регистрация: 03.05.2016
Сообщений: 13
10.05.2016, 23:27  [ТС]     Как взять громкость звукового файла в определенный момент времени? #20
да, заработало
nmcf
5273 / 4593 / 1538
Регистрация: 14.04.2014
Сообщений: 18,243
10.05.2016, 23:29     Как взять громкость звукового файла в определенный момент времени? #21
И в чём было дело?
SHAREN
0 / 0 / 0
Регистрация: 03.05.2016
Сообщений: 13
11.05.2016, 19:16  [ТС]     Как взять громкость звукового файла в определенный момент времени? #22
Честно сказать я просто вставил готовый код.
Оказывается BASS_ChannelGetData берет массив значений в 1 момент времени, а в массив записываются данный начиная с низких частот заканчивая высокими (как в эквалайзере).
А чтобы взять громкость из другого момента времени нужно в цикле менять позиции:
C++
1
2
3
4
        long byte_pos = BASS_ChannelSeconds2Bytes(chan, time);
        BASS_ChannelSetPosition(chan, byte_pos, BASS_POS_BYTE);
        ...
        time += 1 / fps;   //increment time
В общем в самом исходном коде можно прописать
C++
1
2
3
4
char *output_name = "OUTPUT.txt";       // куда запишутся все значения
char *input_name = "INPUT.mp3";             // из какого файла брать значения
double fps = 60;                        // сколько раз в сек. брать спектр
int BANDS = 120;                        // ширина спектра
P.S. а BASS_ERROR_NOPLAY было из-за того что я bass.dll рядом с *.ехе не закинул.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.05.2016, 03:25     Как взять громкость звукового файла в определенный момент времени?
Еще ссылки по теме:
Создание таймер с остановкой в определенный период времени C++
Получить значение амплитуды аудио в заданный момент времени C++
C++ Определение скорости движения автомобиля по прямой в каждый момент времени
C++ Вычислить момент времени когда расстояние между лидирующим и замыкающим велосипедистами будет минимальным
как изменить системную громкость ? C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
SHAREN
0 / 0 / 0
Регистрация: 03.05.2016
Сообщений: 13
12.05.2016, 03:25  [ТС]     Как взять громкость звукового файла в определенный момент времени? #23
Ещё одна проблема, некоторые файлы записываются нормально а некоторые наполовину с нулями.

К примеру в архиве 2 файла, banana.mp3 пишется нормально, 9.mp3 наполовину заполняется нулями.

Так же в 9.mp3 пики намного больше чем в banana.mp3

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
using namespace std;
#include <bass.h>
 
FILE *output_data;
char *output_name = "D:/1.txt";
char *input_name = "D:/9.mp3";
 
//using System;
int main()
{
    DWORD chan,p;
    QWORD pos;
    fopen_s(&output_data,output_name,"w");
 
    BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD,0);         // no audio output, therefore no update period needed
    BASS_Init(0,44100,0,0,NULL);                        // null device, 44100hz, stereo, 16 bits
    chan = BASS_StreamCreateFile(FALSE,input_name,0,0,BASS_SAMPLE_MONO|BASS_STREAM_DECODE);     //streaming the file
 
    pos = BASS_ChannelGetLength(chan,BASS_POS_BYTE);    // вес файла
    printf("streaming file [%llu bytes]",pos);
 
    p = (DWORD)BASS_ChannelBytes2Seconds(chan,pos);
    printf(" %u:%02u\n", p / 60, p % 60);           // длительность файла в сек
 
 
    long byte_pos = 0;
    long byte_pos_ =0;
    int n = 50;             // шаг Hz
    long interval = BASS_ChannelSeconds2Bytes(chan, .1f);       // интервал в секундах
    printf("interval %i \n", interval);
    float peak2 = 0;
 
    while (BASS_ChannelIsActive(chan)) {
        if (byte_pos+interval >= pos)
            break;
        //long byte_pos = BASS_ChannelSeconds2Bytes(chan,fTime);
        BASS_ChannelSetPosition(chan,byte_pos+=n,BASS_POS_BYTE);
        #define SIZE 512
        float fft[SIZE];            // спектр
        BASS_ChannelGetData(chan,fft,BASS_DATA_FFT1024);  //get the fft data, in this case there are 2048 samples
                                                          //binning the fft, modified from bass spectum.c example in sdk.
 
            
            float peak = 0;
            for (int i=0; i < SIZE-1; i++) {
                if (peak < fft[1+i]) {
                    peak = fft[1+i];            // ищем самое большое значение peak на одном спектре
                    //printf("%.0f ", sqrt(peak)*255);
 
                } //printf("%.0f ", sqrt(fft[1+i])*255);
            } //printf("%i %f \n",byte_pos, peak);
                if (BASS_ErrorGetCode())
                    printf("\n%i ERROR %i\n",byte_pos,BASS_ErrorGetCode());
            if (peak2 < peak) {
                peak2=peak;
            }
            //write each column to file
            //fprintf(output_data,"%.0f",sqrt(peak)*255);
        //}
        //endline after every row
        //fprintf(output_data,"\n");
        //pos = BASS_ChannelGetPosition(chan,BASS_POS_BYTE);
        //p = (DWORD)BASS_ChannelBytes2Seconds(chan,pos);
        if (byte_pos_ >= interval) {
            byte_pos_ = 0;
            printf("%i %f \n",byte_pos ,peak2*5);
            fprintf(output_data,"%.0f\n",peak2*5*255);
            peak2=0;
        }
        byte_pos_+=n;
    }
    if(BASS_ErrorGetCode())
        printf("\nERROR %i\n", BASS_ErrorGetCode());
    printf("\nDONE!\n");
    fclose(output_data);
    BASS_Free();
 
    system("pause");
 
    return 0;
}

P.S. а так например с banana.mp3 и другими несколькими файлами на сервере все синхронно визуализировалось, осталось только разобраться с этой проблемой.

а в некоторых других файлах пишет с промежутками, т.е. то идут нули, то файл нормально пишется.

P.P.S.
Вот пример разложенного звукового спектра.http://www.frolov-lib.ru/books/hi1/c...s/image004.jpg, для каждой "плоскости" нужно брать BASS_ChannelGetData
Вложения
Тип файла: rar 9.rar (268.1 Кб, 2 просмотров)
Yandex
Объявления
12.05.2016, 03:25     Как взять громкость звукового файла в определенный момент времени?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru