Filip Skakun on Thu, 12 Apr 2012 21:43:18
I am working on a Windows 8 Metro Style App that does some audio mixing and recording. I have a few problems that I am struggling to solve.
1. Save a mix of multiple voices to a wav file. I could not find any sample or direct API that would show how to do it. My current thinking is to use a submix voice to mix the multiple source voices and create a custom xAPO based on the XAudio2CustomAPO sample from an older DirectX SDK (if custom xAPOs are even approved for Metro-Style Apps) that will copy the output buffer and save it to a wav file stream. Would that work or is there a simpler solution?
2. Is there a way to slow down processing of the source voices - obviously changing the pitch, or even playing the buffers backwards/in reversed direction? I can see how to control the pitch of the voices, but not the speed... I suppose I would need to tweak the buffer that I submit to the source voice?
Chuck Walbourn - MSFT on Thu, 12 Apr 2012 23:35:23
#1 keep in mind that custom APOs run in their own background thread and you really don't want to do a lot of work there. A lock-free pipe or some other low-overhead mechanism can be used to send data to anotehr buffer that can then be written off.
Keep in mind that XAUDIO2's primary purpose is to do real-time dynamic mixing and positioning, so creating WAV files is not really the intent. There are professional audio tools for this kind of offline processing that would be much more effective.
#2 what do you mean by 'speed' of processing?
Filip Skakun on Fri, 13 Apr 2012 00:05:04
Thanks for the answer. I was afraid I would need to carefully shuffle the buffers. What did you have in mind in terms of professional audio tools in terms of ones available for WinRT apps?
By speed I just meant slowing down the playback as in playing a 5s track in 10s.
Chuck Walbourn - MSFT on Fri, 13 Apr 2012 00:15:42
Professional audio tools would create the WAV file. You'd never do it at runtime, just ship the result as part of your app in the first place.
All you have to do so slow down an XAUDIO2 playback is to change the sample rate of the source voice when you create it.
Filip Skakun on Fri, 13 Apr 2012 05:54:56
Well, but that's the core of my game - the ability to mix different audio tracks dynamically - in real time. I want to be able to slow down/stop/reverse playback of all tracks during playback.
Chuck Walbourn - MSFT on Fri, 13 Apr 2012 22:43:05
You can make use of SetSourceSampleRate but you can't have any buffers playing at the time you use it. You could submit your tracks in smaller chunks (say a few seconds of audio data at a time) rather than submit the entire WAV at once so you have some discrete oppourtunities to modify the sample rate before submitting more data.
This API is really intended for 'source voice reuse' not so much for dynamic rate changes which isn't really a common scenario.
Submitting your audio data in smaller chunks is also how you'd be able to do things like reverse the sound 'during play' which again isn't part of standrad XAUDIO2 usage.
Filip Skakun on Fri, 13 Apr 2012 22:46:12
Thanks, that's what I was thinking. I know this is not common, that's why if I am able to implement it - I will get the more unique experience... well, as soon as I can get this xAPO to build. That base class from the XAudio2CustomAPO sample does not port well to C++/CX...
Filip Skakun on Tue, 01 May 2012 09:22:57
Thanks for the help. I did not have the time to play with playback speed much. Reversing playback is pretty straightforward if you just reverse the order of the samples in the input buffer. Using a xAPO to save the output to a file worked OK. I just copy the output buffer to an in-memory buffer and when recording is done - I do some processing on the buffer (convert float samples to 16 bit integer - PCM samples, with reversed big/little-endianness), add a header and get a nice wav file.