Audio Sample Manipulation
-
Monday, June 11, 2012 2:37 AM
Hello, I'm developing an audio application and don't know how to manipulate the data that comes from IAudioCaptureClient ::GetBuffer().
I need to manipulate the sample to change the wave form and produce some bass guitar effects like overdrive, chorus and delay.
I inspect the data from WAVEFORMATEX structure to try to discovery something but I can't.
The code to print the data from WAVEFORMATEX is:
printf("Samples per second: %d\n", pwfx->nSamplesPerSec);
printf("Channels: %d\n", pwfx->nChannels);
printf("Size of extra information: %d\n", pwfx->cbSize);
printf("Block alignment in bytes: %d\n", pwfx->nBlockAlign);
printf("Format type code: %d\n", pwfx->wFormatTag);
printf("Bits per sample: %d\n", pwfx->wBitsPerSample);
printf("Required average data tranfer rate: %d\n", pwfx->nAvgBytesPerSec);And the output is:
Samples per second: 44100
Channels: 2
Size of extra information: 22
Block alignment in bytes: 8
Format type code: 65534 //this code stands for WAVE_FORMAT_EXTENSIBLE
Bits per sample: 32
Required average data tranfer rate: 352800Someone can help me with this?
Thank you
All Replies
-
Monday, June 11, 2012 3:22 PMModerator
When the format type code is WAVE_FORMAT_EXTENSIBLE, cast pwfx to a WAVEFORMATEXTENSIBLE. Then inspect the SubFormat member. See http://blogs.msdn.com/b/matthew_van_eerde/archive/2011/09/09/how-to-validate-and-log-a-waveformatex.aspx
I suspect in this case it will be equal to KSDATAFORMAT_SUBTYPE_IEEE_FLOAT. This means that each sample is a four-byte floating-point integer of type "float".
To back up a step, where are you getting the data from? Is it coming from a recording device like the line in or microphone, or are you doing WASAPI loopback capture from a playback device like the speakers or the headphones?
If you're pulling it from a recording device, you can do what you like with the data and then hand it off to somewhere.
If you're pulling it from a playback device using WASAPI loopback capture, then be aware that WASAPI loopback capture is a read-only tap; modifications you make to the data will not be applied to what goes out of the speakers.
Matthew van Eerde
- Marked As Answer by Guilherme P. Sousa Wednesday, June 13, 2012 2:43 AM
-
Monday, June 11, 2012 5:31 PM
Matthew, i will make the cast after because here I don't have my source code.
I'm getting the data from microphone and want to modify the resulting sound.
Guilherme
-
Monday, June 11, 2012 8:16 PMModerator
OK.
Assuming that the audio is indeed in float format (and the SubFormat will tell you this) you can modify the data in a given packet something like this:
BYTE *pData = NULL;
UINT32 nFrames = 0;
pAudioCaptureClient::GetBuffer(&pData, &nFrames, ...);
float *pFloatData = reinterpret_cast<float*>(pData);
for (UINT32 f = 0; f < nFrames; f++) {
for (WORD c = 0; c < pWfx->nChannels; c++) {
// this is the sample corresponding to the c'th channel in frame f
float sample = pFloatData[f * pWfx->nChannels + c];
// do your processing here
}
}
Matthew van Eerde
- Marked As Answer by Guilherme P. Sousa Wednesday, June 13, 2012 2:43 AM
-
Wednesday, June 13, 2012 2:43 AM
The format is correct Matthew.
Now I must create a temporary buffer to store data before processing.
I'm just starting this project and guess that some problems will arise.
Thanks for your help.


