Я экспериментировал со звуком, используя C.
Я нашел фрагмент кода, который позволил бы мне генерировать звуковой сигнал PCM и выводить его через звуковую карту.
Это сработалодовольно хорошо для того, что это было.
Вот код, который работает: (Вы должны связать winmm, чтобы это работало)
(ВНИМАНИЕ: Это довольно громко.)
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <mmsystem.h>
//#pragma comment(lib, "winmm.lib")
int main()
{
HWAVEOUT hWaveOut=0;
WAVEFORMATEX wfx = {WAVE_FORMAT_PCM,1,8000,8000,1,8,0};
//buffer to hold 1 minute of pcm wave data (8 bit, 8khz sample rate)
char buffer[8000*60];
int i;
for (i=0;i<8000*60;i++){
//generate pseudo-random sound.
buffer[i] = (i*5&(i>>7)|i*3&(i*4>>10));
}
waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);
WAVEHDR header = { buffer, sizeof(buffer), 0, 0, 0, 0, 0, 0 };
waveOutPrepareHeader(hWaveOut, &header, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &header, sizeof(WAVEHDR));
Sleep(60*1000);
waveOutUnprepareHeader(hWaveOut, &header, sizeof(WAVEHDR));
waveOutClose(hWaveOut);
return 0;
}
Тем не менее, я хотел проанализировать и воспроизвести файлы .wav, используя аналогичный метод.
Я понял, что, хотя приведенный выше код работает (где статически размещается буфер) Тем не менее, когда я выделяю память динамически (используя mallocнапример), нет воспроизводимого звука.Я слышу очень хриплый гудящий звук, который указывает, что была выполнена функция waveOutWrite()
, но нет другого воспроизводимого звука.
Вот пример, который не работает:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <mmsystem.h>
//#pragma comment(lib, "winmm.lib")
int main()
{
HWAVEOUT hWaveOut=0;
WAVEFORMATEX wfx = {WAVE_FORMAT_PCM,1,8000,8000,1,8,0};
//buffer to hold 1 minute of pcm wave data (8 bit, 8khz sample rate)
char *buffer = malloc(sizeof(char)*8000*60);
int i;
for (i=0;i<8000*60;i++){
//generate pseudo-random sound.
buffer[i] = (i*5&(i>>7)|i*3&(i*4>>10));
}
waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);
WAVEHDR header = { buffer, sizeof(buffer), 0, 0, 0, 0, 0, 0 };
waveOutPrepareHeader(hWaveOut, &header, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &header, sizeof(WAVEHDR));
Sleep(60*1000);
waveOutUnprepareHeader(hWaveOut, &header, sizeof(WAVEHDR));
waveOutClose(hWaveOut);
return 0;
}
Примечание: я слышал, что есть способ «заблокировать» часть памяти, и я мог бы использовать это для воспроизведения аудио-буфера, который был динамически распределен.Если так, то как бы я это сделал?
У меня тоже есть небольшое раздражение.Я обнаружил, что если я запускаю программу без наушников, звук воспроизводится через динамики моего компьютера, что и ожидается, но когда я подключу наушники, звук все равно будет продолжать воспроизводиться через динамики компьютера.Как бы я изменил код так, чтобы он заменял устройство воспроизведения на значение по умолчанию, если устройство воспроизведения по умолчанию изменяется?
Большое спасибо за потраченное время!Вы, люди, потрясающие.
Обновление:
Я обнаружил, что документация Microsoft использует функции GlobalAlloc()
, HeapAlloc()
, LocalAlloc()
и VirtualAlloc()
для выделения памяти для волновых буферов.Код ниже взят из этого примера :
char *buffer = LocalAlloc(LMEM_FIXED,8000*60); //Doesn't work. Still no sound.
Это также взято из другого примера :
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, 8000*60);
char *buffer = GlobalLock(hData); //Also doesn't work, no sound.