views:

178

answers:

2

Hi.

Anyone knows of a sensible way to create an ARBITRARY sound wave in C# and play it back from the speakers?

This issue has been coming back to every now and then for years, I always end up giving it up after a lot of failure without finding a solution.

What I want to do is like a reverse-visualizer, that is, I don't want to generate "numbers" from sound, I want to generate sound from numbers.

Like get a function that I provide with sample rate, sample size, and the sound data (an array of integers for example), and it would generate the appropriate wav file from it (real-time sound playback would be ideal, but I'd be more than pleased with this too).

I know the wav file specifications are all over the interweb, and did make several attempts creating the above function, had some success for low frequencies, but once I start messing with bits per sample etc... it becomes a HUGE, uncontrollable mess.

Is this not already done in any way? I wouldn't mind what it uses, as long as there's a .NET managed wrapper for it (and I can access it from the most recent VS to time). XNA doesn't support low level audio this way. Also found several examples that claim to achieve something similar, but they either don't work at all, or do something entirely different.

Thank you.

+1  A: 

FMOD can do sample loads from memory and has a C# wrapper.

Kawa
Okay, just had a lot of things coming up so couldn't experiment that much yet I'm sorry. FMOD definitely can do it, but it has a terrible auto-generated managed wrapper. There's a specific example of doing this with certain settings, but it's a pain to change those settings and it forces developers to use unsafe code everywhere. Thank you for pointing it out thought, when I'll have more time I'll ask them why I couldn't use over 2 bytes per sample settings.
jssyjrm
+3  A: 
arx
This looks really awesome, and I feel really ashamed but didn't have the time to really play with it yet. Just one question: Is it easy to make it 4 bytes per sample?
jssyjrm
You can make it 4 bytes per sample but I don't know if Windows will play it. It might, I just don't know. Anyway, if you want to do this change all references to sizeof(short) to sizeof(int), change the sample type to int, change the scaling factor (short.MaxValue) to int.MaxValue and fix the loop that fills the byte array to add four bytes per sample. But I'd be surprised if you can hear a difference.
arx