I have been struggling with this for ages and ages and I'm starting to really get fed up,
No matter what I try or study on I simply cannot output a sound that is not choppy regardless of how I set up the memory, few blocks, more blocks, big blocks, small blocks, different loops, different call-backs, etc, nothing seems to work and I always get a choppy sound,
I'd really appreciate if someone who know what they're doing look over my code and explain where I go wrong, the littlest of detail is appreciated to the upmost degree.
Even if you can recommend someone or somewhere to contact / post please inform me!
#include <iostream>
#include <Windows.h>
#include <cmath>
#pragma comment(lib, "Winmm.lib")
VOID ParseError(MMRESULT Result, LPCWSTR FunctionName)
{
if (Result != MMSYSERR_NOERROR)
{
WCHAR Text[256];
waveOutGetErrorText(Result, Text, 256);
#ifdef _IOSTREAM_
std::wcout << "\'" << FunctionName << "\'" << " : " << Text << std::endl;
#endif
MessageBox(NULL, Text, FunctionName, MB_OK);
}
}
typedef short TYPE;
UINT16 U_BlockCount;
UINT16 U_BlockSize;
UINT16 U_BlockCurrent;
UINT8 U_Channel;
UINT32 U_SampleRate; // Sample Rate In Hz
UINT32 U_SampleSize; // Sample Size In Bits
TYPE* T_Memory = nullptr;
WAVEHDR* W_Header;
WAVEFORMATEX S_WaveFormat;
HWAVEOUT H_Waveout;
HANDLE H_Mutex;
double OutPutWave()
{
double Output;
static double Time = 0;
Output = sin(Time * 2 * 3.153);
Time += 0.01;
return Output;
}
void Write(HWAVEOUT Waveout)
{
ParseError(waveOutUnprepareHeader(Waveout, &W_Header[U_BlockCurrent], sizeof(W_Header[U_BlockCurrent])), L"waveOutUnprepareHeader");
ParseError(waveOutPrepareHeader(Waveout, &W_Header[U_BlockCurrent], sizeof(W_Header[U_BlockCurrent])), L"waveOutPrepareHeader");
ParseError(waveOutWrite(Waveout, &W_Header[U_BlockCurrent], sizeof(WAVEHDR)), L"waveOutWrite");
}
void CALLBACK waveOutProc(HWAVEOUT Waveout, UINT uMsg)
{
U_BlockCurrent = (U_BlockCurrent + 1) % U_BlockCount;
if (uMsg == WOM_DONE) Write(Waveout);
}
INT main()
{
H_Mutex = CreateMutex(NULL, FALSE, NULL);
U_BlockCount = 4;
U_BlockSize = 1000;
U_BlockCurrent = 0;
U_SampleRate = 44100;
U_SampleSize = sizeof(TYPE) * 8;
U_Channel = 2;
S_WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
S_WaveFormat.cbSize = 0;
S_WaveFormat.nChannels = U_Channel;
S_WaveFormat.nSamplesPerSec = U_SampleRate;
S_WaveFormat.wBitsPerSample = U_SampleSize;
S_WaveFormat.nBlockAlign = S_WaveFormat.nChannels * (S_WaveFormat.wBitsPerSample / 8);
S_WaveFormat.nAvgBytesPerSec = S_WaveFormat.nSamplesPerSec * S_WaveFormat.nBlockAlign;
T_Memory = new TYPE[U_BlockCount * U_BlockSize];
ZeroMemory(T_Memory, sizeof(TYPE) * U_BlockCount * U_BlockSize);
W_Header = new WAVEHDR[U_BlockCount];
ZeroMemory(W_Header, sizeof(WAVEHDR) * U_BlockCount);
for (UINT Idx = 0; Idx < (U_BlockCount * U_BlockSize); Idx++)
{
T_Memory[Idx] = 440 * OutPutWave() * 10;
}
for (UINT Idx = 0; Idx < (U_BlockCount); Idx++)
{
W_Header[Idx].dwBufferLength = sizeof(TYPE) * U_BlockSize;
W_Header[Idx].lpData = (LPSTR)T_Memory + (Idx * U_BlockSize);
}
ParseError(waveOutOpen(&H_Waveout, WAVE_MAPPER, &S_WaveFormat, (DWORD_PTR)waveOutProc, (DWORD_PTR)NULL, CALLBACK_FUNCTION), L"waveOutOpen");
Write(H_Waveout);
while (true);
return 0;
}