Realtime sound sample manipulation
BlitzMax Forums/BlitzMax Programming/Realtime sound sample manipulation
| ||
I'd like to write to the samplebuffer directly, and have the changes played back the next time the sample loops. I've done this in PowerBasic in the past with a Windows only solution. In Blitzmax, it seems manipulating a buffer used in CreateStaticAudioSample(), doesn't yield any results unless i reload the sound. Is it possible in native Bmax or do I need a lib? |
| ||
You could do it with OpenAL, creating your own audio buffer data as necessary. |
| ||
I have done it with the FMOD module, but it's a bit of a pain and involves some C programming (unless the garbage collector has improved to the point where the callback could be written in Blitz without bizarre errors, since I last tried.) I think Taron recently did something similar to what you're attempting, so invade one of his threads and ask. |
| ||
Well, well... I'm really just doing hardcore looping by not only reloading a sample piece, but the generating and reloading the whole thing, which is everything but what you'd want. My goal hasn't been to do a realtime synth, because during a game it would only additionally burden the cpu (unless multithreaded and even then I would likely find a better use for the second thread...). Anyway, I do love the idea of a realtime synth and also keep my eyes open for good suggestions using bmax. I do, however, want to learn more about including c libs and code snippits, since I am natively rather a C guy, yet not in regards to entire applications but rather for writing plugins. I've never done any audio programming, so this is my first time ever. It's remarkably dissimilar to graphics programming, due to the 1 dimentional aspect of it and the need to do many things on the fly in one go. Makes you think differently, but it's great! In the last two weeks I've learned unbelievable amounts about sound programming, but also interface coding and the likes. All stuff I've never done to that extend or at all. As for Fmod, I think I just don't like to make myself depend on things, particularely if they are somewhat restrictive (license stuff included). Souns paradox for new BlitzMax programmer to say, but well... I hope you know what I mean. Two things to find out: - implementing C code - Basic DirectAudio or OpenAL coding in C That's all, and I'm sure we'll be ready to rock! 8) |
| ||
Thanks guys. For now it looks like OpenAL or some native Windows stuff if I can dig it out of my archives then. |
| ||
this code should/may still work with freeaudio multimedia drivers: tfloat synth test |
| ||
Thanks skidracer, but I can't get the Freeaudio driver to initialise. [EDIT]: "Freeaudio Multimedia" does initialise, but nothing happens when I write to the sample buffer after Loadsound has been called Am I missing something? Below is my testcode, clipped together from the examples in the other thread. With "FreeAudio DirectSound" I get the noise when it's unrem'ed and run before LoadSound(), but I can't change the samples in the mainloop. |
| ||
Hi Peter, sorry to waste your time, I'll try and have a look at freeaudio streaming this weekend hopefully. |
| ||
Don't be sorry, it's great if you can look into it. It might very well be me not quite grasping the finer details. I updated your code like shown below. It runs and readpos returns what looks like valid results to me by casting the channel to a TFreeAudioChannel , but I still get no sound. |
| ||
If your interested I'll be releasing the new MaxMod2 module soonish. A simple example using MaxMod2.CallbackStream works like this ATM... Import MaxMod2.PortAudio Import MaxMod2.CallbackStream Local Chn:TChannel = CreateAudioCallbackStream(New TAudio) Repeat Delay 1 Until ChannelPlaying(Chn)=0 Type TAudio Extends TCallbackStream Field p!, p1! Method New() SampleRate = 11025 ' set required samplerate Channels = 1 ' set the number of channels Bits = 16 ' set bits per channel EndMethod Method FillBuffer:Int(output:Byte Ptr,size:Int) Local AudioPtr:Short Ptr = Short Ptr(output) ' get our pointer to the output Local n:Int,av! ' make some local variables For n=0 Until size/2 ' loop to process the output buffer av=Sin( Sin(p1^2)*ATan(p^3)*20000 )*5000 ' calculate our audio value If p1<1 Then av:*p1 ' add a simple fade in AudioPtr[n] = av ' apply audio value to output p:+0.5 ; p1:+0.00009 ' increment for next pass If p>1000000 Exit; ' stop when p>1000000 Next Return n*2 ' return number a bytes written to output. ' a return value less than 'size' ' causes the stream to stop EndMethod EndType latency isnt to bad at about a 10th of a second, and of course all the standard TChannel commands work on the stream too. *EDIT* excuse the borked tabbing |
| ||
@REDi : Looks just like what I'm looking for. How do I set the bufer size? I'll be looking forward to the release of maxmod2 ! Is there a beta? :-) |
| ||
How do I set the bufer size? The circular buffer size is handled internally and is normally <100 millisecs (depending on audio driver used), but the amount of audio you want to play is up to you, as soon as you return less than the requested amount of audio it assumes you're all done and ends when its finished playing what you've given it, so you can play a couple of millisecs or hours worth :) Is there a beta? :-) the first couple of releases are always beta for me, until people stop finding problems ;) I'll hopefully be able to release in a couple of days. |
| ||
So if my aim is to play a looping 32ms tone, I'll handle the looping by writing it at least 1102/353 (3.1'ish) times to the buffer, and remember the loop offset between runs? (assuming 32ms ~ 353 samples at 11025.) [EDIT]: Okay, to make it easy on myself, I 'll write it 4 times?... :-) |