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

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

Войти
Регистрация
Восстановить пароль
 
_Ivana
2884 / 1709 / 148
Регистрация: 01.03.2013
Сообщений: 4,883
Записей в блоге: 2
#1

Прочитать несколько секунд wav файла в массив - C++

23.08.2014, 16:27. Просмотров 1079. Ответов 2
Метки нет (Все метки)

Есть win32 проект в Студии. Задача - запросить диалог выбора wav файла, проверить что это wav файл, прочитать его хедер, взять оттуда нужные данные в виде чисел - битрейт, количество каналов, формат и т.п. и затем прочитать заранее заданное количество отсчетов в заранее приготовленный для них массив. Причем, если файл будет моно, то отсчеты читаются как есть, если стерео - то при кодировке центральный/разностный считывается только центральный канал, при правый/левый - среднее арифметическое. Если файл будет не 16-битный, то приводим его в 16 бит - домножаем или делим отсчеты на коэффициент. Я сейчас ооочень коряво реализовал чтение моно вавки, но подозреваю что и здесь у меня полно ошибок, например при прочтении хедера даже не могу взять параметры файла. Как это можно сделать по-нормальному? Если будет реализовано по ООП-шному через классы, то разберусь. Если через дополнительные библиотеки - то смотря какие, WinMM.Lib у меня уже так и так используется, а другие не хотелось бы подключать. Хотя если с ними будет красиво и стройно, то тоже придется.
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
void ReadWav_Proc(HWND hWnd)
{
    SetWindowTextW(hwndSta1, L"Read...");
    HANDLE hFile = INVALID_HANDLE_VALUE;
    if((hFile = CreateFile(L"Test.wav", GENERIC_READ, FILE_SHARE_READ,
        NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) {
        SetWindowTextW(hwndSta1, L"Не могу открыть файл");
        return;
    }
    WAVEHDR WaveTestHdr;
    DWORD readBytes;
    wchar_t buf[20];
 
    if (ReadFile(hFile, &WaveTestHdr, sizeof(WAVEHDR), &readBytes, NULL)) {
        wsprintfW(buf, L"%lu", readBytes);
        SetWindowTextW(hwndSta1, buf);
    } else {
        SetWindowTextW(hwndSta1, L"Не могу прочитать хедер файла");
        return;
    }
    if (ReadFile(hFile, waveOut.buf, sizeof(waveOut.buf), &readBytes, NULL)) {
        wsprintfW(buf, L"%lu", readBytes);
        SetWindowTextW(hwndSta1, buf);
    } else {
        SetWindowTextW(hwndSta1, L"Не могу прочитать данные файла");
        return;
    }
    CloseHandle(hFile);
}
Добавлено через 1 час 17 минут
UPD заголовки вроде уже читаю
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
typedef struct  WAV_HEADER{
        char                RIFF[4];        // RIFF Header      Magic header
        unsigned long       ChunkSize;      // RIFF Chunk Size
        char                WAVE[4];        // WAVE Header
        char                fmt[4];         // FMT header
        unsigned long       Subchunk1Size;  // Size of the fmt chunk
        unsigned short      AudioFormat;    // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
        unsigned short      NumOfChan;      // Number of channels 1=Mono 2=Sterio
        unsigned long       SamplesPerSec;  // Sampling Frequency in Hz
        unsigned long       bytesPerSec;    // bytes per second
        unsigned short      blockAlign;     // 2=16-bit mono, 4=16-bit stereo
        unsigned short      bitsPerSample;  // Number of bits per sample
        char                Subchunk2ID[4]; // "data"  string
        unsigned long       Subchunk2Size;  // Sampled data length
 
    }my_wav_hdr;
    my_wav_hdr WaveTestHdr;
 
    DWORD readBytes;
    wchar_t buf[500];
    if (ReadFile(hFile, &WaveTestHdr, sizeof(WaveTestHdr), &readBytes, NULL)) {
        wsprintfW(buf, L"%.4S %lu %.4S %.4S %lu %u %u %lu %lu %u %u %.4S %lu",
            WaveTestHdr.RIFF,
            WaveTestHdr.ChunkSize,
            WaveTestHdr.WAVE,
            WaveTestHdr.fmt,
            WaveTestHdr.Subchunk1Size,
            WaveTestHdr.AudioFormat,
            WaveTestHdr.NumOfChan,
            WaveTestHdr.SamplesPerSec,
            WaveTestHdr.bytesPerSec,
            WaveTestHdr.blockAlign,
            WaveTestHdr.bitsPerSample,
            WaveTestHdr.Subchunk2ID,
            WaveTestHdr.Subchunk2Size);
        SetWindowTextW(hwndSta1, buf);
    } else {
        SetWindowTextW(hwndSta1, L"Не могу прочитать хедер файла");
        return;
    }
Непонятно только, почему структура заголовка вав файла не задефайнена в ММ-библиотеке, пришлось объявлять свою... Или она там кусками задефайнена, т.к. разные вавки имеют различную структуру заголовков?...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.08.2014, 16:27     Прочитать несколько секунд wav файла в массив
Посмотрите здесь:
C++ Как прочитать несколько байт из файла с n-го бита
C++ Чтение самплов из wav файла в массив
C++ Как прочитать первую строку из файла а остальной текст повторить несколько раз?
С текстового файла прочитать массив C++
С текстового файла прочитать одномерный массив C++
Прочитать массив из файла и вывести на экран C++
Прочитать из текстового файла данные в массив структур C++
Прочитать строку из файла и записать ее в массив структуры C++
прочитать массив из файла и отсортировать его по возрастанию C++
Прочитать массив из файла, изменить, вывести в другой файл C++
Прочитать из файла массив, отсортировать, результат вывести на экран. C++
C++ Простой вопрос по СРР - как из файла прочитать в булев массив?

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kaliban
3 / 3 / 0
Регистрация: 13.04.2012
Сообщений: 47
23.08.2014, 19:51     Прочитать несколько секунд wav файла в массив #2
Попробуй перезагрузить компьютер.
_Ivana
2884 / 1709 / 148
Регистрация: 01.03.2013
Сообщений: 4,883
Записей в блоге: 2
24.08.2014, 01:12  [ТС]     Прочитать несколько секунд wav файла в массив #3
Собственно, я перезагрузил компьютер , дописал немножко кода и получилась почти готовая программка, решающая следующую задачу: есть некая система передачи звука по радиоканалу, для ее тестирования вход системы подключается к выходу звуковой карты компа, выход системы ко входу звуковой карты, на компе запускается эта программка, которая позволяет выбрать wav файл из каталога, загружает 10 секунд (или меньше, если файл короче) одного канала из него в память, рисует график в верхнем окне. По команде "старт" эти загруженные данные запускаются на воспроизведение, через звуковую карту идут в эфир, принимаются на вход и записываются в память и рисуется график принятого звука в нижнем окне. Графики зумятся кнопками мыши и скролятся полосой прокрутки (немножко недоделан вызов всех ее вариантов) зависимо (можно сделать независимо). Оператор глазально видит отличия в амплитудах/задержках разных графиков, подстраивает параметры системы передачи и снова нажимает старт или выбирает другой тестовый файл. При необходимости входящие данные также можно записать (пока не доделал ) в wav файл для последующего анализа в разных спектралабах. Написано на чистом С и не менее чистом winapi, использую только 2 библиотеки - WinMM.Lib для ввода/вывода аудио и comdlg32.lib для диалога выбора файла. Хотел прикрепить код, да движок форума ограничивает максимальное сообщение в 20000 символов
Yandex
Объявления
24.08.2014, 01:12     Прочитать несколько секунд wav файла в массив
Ответ Создать тему
Опции темы

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