How do i access the sound buffer for win32 ?

Started by
12 comments, last by the incredible smoker 6 years, 7 months ago

Hi, i have a question about accessing the sound buffer for win32.

How do i do that ?

 

I like to fill it with bytes, so i can generate realtime digital audio.

 

thanks in advance

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

Advertisement

You don't have direct access to the kernel mixer from user-mode applications. Instead, use a low-level API such as XAudio. This allows you to submit your own buffers to be mixed to the audio output.

Niko Suni

Hi, thanks for the reply, i dont like to install stuff on my PC, also dont like to make end-users install stuff.

I had found some code ( untested ) once, only i lost it and cant find it back.

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

XAudio is a system component that, I believe, is installed as part of Windows.

Any applications that play sound effectively need to go through the system-supplied interfaces, be it XAudio or something equivalent.

Applications generally don't call drivers directly; there is always at least one abstraction layer between them.

DirectSound, SDL, Core Audio and DirectShow are examples of alternatives for XAudio, but not one of them provides you direct access to the primary sound buffer. And for a good reason.

 

Niko Suni

you can do it the way he does, video below. He also has your same interest in mind of not having users need to install stuff, so this probably is what you need.

 

XAudio is effectively the successor to DirectSound, and it is a separate library in the same sense as XAudio is. BOTH of them are pre-installed in modern Windows versions.

Moreover, XAudio is easier to use than DS, and has lower latency as well :D

 

Niko Suni

Or you go into WINAPI level and use the Waveform API or the newer WASAPI functions to that are part of Windows up from NT (Waveform) and Windows 7 (WASAPI)

This small XAudio2 example should work as is on Windows 10. For earlier versions, change the dll name as needed. This is not production-ready code because it does not perform any error checking whatsoever. In particular, one should check for success on every API call before proceeding, and in case of heap allocation, check that the memory was actually available. Also, typically audio APIs are used in applications with event loops (as in windows desktop apps), so that playing a single sound buffer is not the last thing the program does before exiting.


// XAudioDemo.cpp : Defines the entry point for the console application.
//
// NO WARRANTY! The code provided is just for example purposes.
// The code below skips almost all error checking so it should not be used in production applications as is.
// In real code we should check for failure and success for all API calls and memory allocations.

// -Niko

#include "stdafx.h"

/*
In addition to the default console app headers, we include the following in stdafx.h:

#include <Windows.h>
#include "XAudio2.h"
#include <cmath>
*/

typedef HRESULT WINAPI xaudio2_create(IXAudio2**, UINT32, XAUDIO2_PROCESSOR);

int main()
{
	CoInitializeEx(0, 0);
	HMODULE XAudioLib = LoadLibrary(L"xaudio2_9.dll"); // for windows 10, use XAudio 2.9
	xaudio2_create* xaudiocreate;
	xaudiocreate = (xaudio2_create*)GetProcAddress(XAudioLib, "XAudio2Create");

	IXAudio2 *pxaudio = NULL;
	xaudiocreate(&pxaudio, 0, XAUDIO2_DEFAULT_PROCESSOR);

	IXAudio2MasteringVoice *pMasteringVoice = NULL;
	pxaudio->CreateMasteringVoice(&pMasteringVoice, XAUDIO2_DEFAULT_CHANNELS, 22050);

	IXAudio2SourceVoice *pSourceVoice = NULL;
	WAVEFORMATEX sourceFormat;
	sourceFormat.cbSize = 0;
	sourceFormat.nAvgBytesPerSec = 22050 * 2;
	sourceFormat.nBlockAlign = 2; // 2 bytes per sample
	sourceFormat.nChannels = 1; // mono
	sourceFormat.nSamplesPerSec = 22050;
	sourceFormat.wBitsPerSample = 16;
	sourceFormat.wFormatTag = WAVE_FORMAT_PCM;

	pxaudio->CreateSourceVoice(&pSourceVoice, &sourceFormat);

	XAUDIO2_BUFFER buffer = { 0 };
	
	buffer.Flags = XAUDIO2_END_OF_STREAM;

	INT16* sampleData = new INT16[22050 * 2]; // 2 seconds of 22050Hz mono data

	// sound synthesis
	for (int i = 0; i < 22050 * 2; ++i)
	{
		double sv = std::sin((double)i / (double)22050 * 5000.0); // sine wave
		sampleData[i] = sv * 32767.0; // amplify from -1...1 to sample range
	}

	buffer.AudioBytes = 22050 * 2 * 2;
	buffer.pAudioData = (BYTE*)sampleData;
	pSourceVoice->SubmitSourceBuffer(&buffer);
	pxaudio->StartEngine();

	pSourceVoice->Start(0, XAUDIO2_COMMIT_NOW);

	// Since we are in a console app, we need to sleep here so as to not exit immediately.
	// In desktop apps, we could handle the XAudio voice callbacks instead.

	Sleep(2000); 
	pxaudio->StopEngine();
	delete[] sampleData;

    return 0;
}

 

Niko Suni

Thanks all, i will look into it,

How about windows XP ?

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

There is a redistributable available for XP. However, XP in general is an unsafe platform nowadays because MS does not support it with security updates anymore.

Niko Suni

This topic is closed to new replies.

Advertisement