locked
Need some help with XAudio2

    Question

  • Hi all, I've been trying to get XAudio2 up and running per the many examples/tutorials on the net, but I've run into a snag. Namely, no matter what I try, I have been unable to get any sounds to play. 

    Here's my initialization code:

    	//Audio init section
    
    	if(FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
    	{
    		return false;
    	}
    	UINT32 flags = XAUDIO2_DEBUG_ENGINE;
    
    	if(FAILED(XAudio2Create(&g_xAudioEngine,flags)))
    	{
    		MessageBox(NULL, L"Failed on XAudio2Create", L"Sadface", MB_OK);
    		CoUninitialize();
    		return false;
    	}
    	
    	if(FAILED(g_xAudioEngine->CreateMasteringVoice(&g_masterVoice, XAUDIO2_DEFAULT_CHANNELS,(UINT32) SAMPLERATE, 0,0,NULL)))
    	{
    		MessageBox(NULL, L"Failed to create mastering voice!", L"Sadface", MB_OK);
    		CoUninitialize();
    		return false;
    	}
    	XAUDIO2_BUFFER buff = {0};
    	WAVEFORMATEX wfx = {0};
    
    	wfx.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
    	wfx.nChannels = 1;
    	wfx.nSamplesPerSec = 44100;
    	wfx.nAvgBytesPerSec = 44100 * sizeof(float);
    	wfx.nBlockAlign = sizeof(float);
    	wfx.wBitsPerSample = sizeof(float) * 8;
    	wfx.cbSize = 22;
    
    	WAVEFORMATEXTENSIBLE wfxe = {0};
    	wfxe.Format = wfx;
    	wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
    	wfxe.Samples.wValidBitsPerSample = 32;
    	wfxe.dwChannelMask = SPEAKER_FRONT_CENTER;
    	
    
    	std::stringstream debugstream;
    
    	debugstream << "nBlockAlign: " << wfx.nBlockAlign << " bitspersample: " << wfx.wBitsPerSample << std::endl;
    	OutputDebugStringA(debugstream.str().c_str());
    
    	
    	if(FAILED(g_xAudioEngine->CreateSourceVoice(&g_sourceVoice, (WAVEFORMATEX*)&wfxe)))
    	{
    		MessageBox(NULL, L"Failed to create source voice!", L"sadface", MB_OK);
    	}
    	

    My sample rate here (specified by the SAMPLERATE constant) is 44100 Hz. I've also tried other sample rates including the default native sample rate (48kHz). In addition to this, I've also tried signed int 16 as the data type (using format WAVE_FORMAT_PCM) and __int16 sized data. 

    Here is the code I'm using to submit a buffer to the source voice. It's called once per second with a boost asio timer, and generates one second of data:

    void streamNextChunk(const boost::system::error_code& error, boost::asio::deadline_timer & timer)
    {
    	static bool comInitThisThread = false;
    	if(!comInitThisThread)
    	{
    		CoInitializeEx(NULL, COINIT_MULTITHREADED);
    		comInitThisThread = true;
    	}
    	timer.expires_from_now(boost::posix_time::milliseconds(1000));
    	timer.async_wait(boost::bind(streamNextChunk, _1, boost::ref(timer)));
    
    	static __int64 sampleCount = 0;
    	float* buff = new float[44100];
    	
    	for(size_t i = 0 ;i < 44100; i++)
    	{
    		float t = (float)sampleCount++;
    		t /= 44100.0;
    		buff[i] = cos(2 * 3.14159 * t * 260);
    		
    	}
    	
    	XAUDIO2_BUFFER xAudioBuff = {0};
    	xAudioBuff.AudioBytes = (44100) * sizeof(float);
    	xAudioBuff.pAudioData = (BYTE*) buff;
    	
    	if(FAILED(g_sourceVoice->SubmitSourceBuffer(&xAudioBuff)))
    	{
    		OutputDebugStringA("Failed on submit source buffer!!! D:\n");
    	}
    
    	
    	g_sourceVoice->Start(0, XAUDIO2_COMMIT_NOW);
    	XAUDIO2_VOICE_STATE state;
    
    	g_sourceVoice->GetState(&state);
    	float volume; 
        g_sourceVoice->GetVolume(&volume);
    	std::stringstream debugstream;
    	float gvolume;
    	g_masterVoice->GetVolume(&gvolume);
    	debugstream << "PTR: " << buff << " Q: " << state.BuffersQueued << " S: " << state.SamplesPlayed << " SC: " << sampleCount << " V: " << volume << " GV: " << gvolume << std::endl;
    
    	OutputDebugStringA(debugstream.str().c_str());
    	
    }

    As you can see, I am attempting to generate a simple tone at 260 Hz (originally this was at 2600Hz but I changed it as part of my attempts to debug the issue). Yes, I am aware that this leaks memory, however at the current time I am more concerned with getting the app to produce some sound. Elsewhere in the program I am setting the volume of both the source and master voices to 224. The debug printout in the streamNextChunk function confirms this is the volume the voices are set for. 

    At best I have only been able to to get the program to produce a click or two sound-wise. I was able to do this by changing the timing rate of the streamNextChunk function so that it gets called, for example, every 1.2 seconds, but only generates 1 second of data. Other than this I have not been able to get the application to generate any real sound. I have also tried changing the source function from a tone to random white noise to no avail.

    According to the MSDN examples and tutorials I have read on XAudio2, this should work without a problem. Can anyone see anything obvious that I'm missing or suggest something I can try to resolve the problem?

    Thanks.

    Wednesday, January 02, 2013 11:48 PM

Answers

  • Assuming you are using XAUDIO 2.8 on Windows 8, have you tried looking for debugging information in the Event Viewer?

    • Go to Control Panel, Administrative Tools, Event Viewer.
    • View->Show Analytic and Debug Logs
    • Applications and Services Logs / Microsoft / Windows / XAudio2.
    • Right click on Microsoft Windows XAudio2 debug logging, Properties, then Enable Log and hit OK
    • Marked as answer by Jesse Jiang Wednesday, January 09, 2013 2:06 AM
    Wednesday, January 02, 2013 11:57 PM
  • Try using SetDebugConfiguration to make it more 'verbose'
    • Proposed as answer by Jesse Jiang Tuesday, January 08, 2013 7:55 AM
    • Marked as answer by Jesse Jiang Wednesday, January 09, 2013 2:06 AM
    Thursday, January 03, 2013 7:33 PM

All replies

  • Assuming you are using XAUDIO 2.8 on Windows 8, have you tried looking for debugging information in the Event Viewer?

    • Go to Control Panel, Administrative Tools, Event Viewer.
    • View->Show Analytic and Debug Logs
    • Applications and Services Logs / Microsoft / Windows / XAudio2.
    • Right click on Microsoft Windows XAudio2 debug logging, Properties, then Enable Log and hit OK
    • Marked as answer by Jesse Jiang Wednesday, January 09, 2013 2:06 AM
    Wednesday, January 02, 2013 11:57 PM
  • Ahh, sorry, I forgot to mention the OS and version.

    I'm on Windows 7 with XAudio2 2.7 (June 2010 SDK version).

    I followed your suggestion and checked for debugging info in the Event Viewer, however there's no listing for XAudio2. I'm not sure if this means the logging isn't enabled or that there are no events to report. 

    I also haven't seen any debug output messages through MSVC from the engine, which mildly concerns me, as I'd expect to see some audio glitch warnings or buffer starvation warnings when I purposely starved the source voice during my debug attempts (I saw none). 

    Thursday, January 03, 2013 12:06 AM
  • On Windows 8, you can use the ETW events which are built into the system.

    For XAUDIO 2.7, you use the XAUDIO2_DEBUG_ENGINE flag and look for debug output.

    Thursday, January 03, 2013 1:09 AM
  • I have XAUDIO2_DEBUG_ENGINE enabled, and I'm not seeing any debug output warnings, even when I purposely starve the source voice, which I find mildly concerning. Printing out the samples played from state.SamplesPlayed shows an increasing sample count, and printing out the number of buffers queued shows at most 2 buffers, but usually 1.

    Thursday, January 03, 2013 2:23 AM
  • Try using SetDebugConfiguration to make it more 'verbose'
    • Proposed as answer by Jesse Jiang Tuesday, January 08, 2013 7:55 AM
    • Marked as answer by Jesse Jiang Wednesday, January 09, 2013 2:06 AM
    Thursday, January 03, 2013 7:33 PM