Page 1 of 1
gapless sample replay - how to do?
Posted: Wed Nov 24, 2010 9:29 pm
by zylesea
I am writing a program where I calulate some data and replay that as sample.
But the replay is stuttering.
Let's assume the basic layout of the program looks like that:
Code: Select all
Function p_DoSomethingComputingIntensive()
... [many operations]...
EndFunction
Function p_CalculateSample()
For k=0 To 2499
noise[k]=Rnd (max_noise)
Next
CreateSample(1, noise, 10000)
EndFunction
Function p_mainthing()
p_DoSomethingComputingIntensive()
p_CalculateSample()
PlaySample (1)
EndFunction
SetInterval(0, p_mainthing, 125)
Repeat
WaitEvent
Forever
The buffer for the sample is as big as required for a 125 ms sample. A bigger buffer won't cure the stuttering. I guess the prob is that the sample replay is not an operation leaving the main loop once triggered but keeps the loop locked for the time of the replay. All operations of one loop repetition take less than 125 ms (cpu load at about 35%), hence a gapless should be possible somehow and I think more or less every program doing sample replay does it. But I don't know how to achieve that.
Re: gapless sample replay - how to do?
Posted: Fri Nov 26, 2010 3:38 pm
by airsoftsoftwair
I'm afraid that's currently not possible. We would need a new API to support playback of dynamically generated PCM data. For example, something like
Code: Select all
CreateDynamicMusic(1, p_StreamFunc, 44100)
PlayMusic(1)
Hollywood would call p_StreamFunc() every second and p_StreamFunc() would have to return the hertz number of new PCM samples in a table. But it's quite difficult to support such a functionality because sound playback is lowlevel stuff and the implementation is very different on each platform Hollywood supports, so it's likely to take a lot of time.
Re: gapless sample replay - how to do?
Posted: Tue Feb 21, 2012 2:07 pm
by airsoftsoftwair
Hollywood 5.0 now supports gapless sample replay. Have a look at the Synthesizer example.
Re: gapless sample replay - how to do?
Posted: Sat Feb 25, 2012 1:06 am
by zylesea
Thanks Andreas!
Daumen hoch & super Sache!
Will place an order within the very next days.
And the network thing is also cool. And the doublebuffering. And the vector things. And the #?
The list is really long and pretty impressive!
Re: gapless sample replay - how to do?
Posted: Thu Apr 26, 2012 11:10 am
by zylesea
Well, I have issues with a delay during gapless replay I cannot explain. The changes in data providing the stream are affecting the acual stream with quite a delay (1-2s). Just look to the little example code provided below.
Dunno why that is the case. If you press the button (the red box), it takes a while until the audio changes, albeit the box changes its colour rather immediaely. I don't understand what makes that delay. I also know that it is possible to modify the audio output realtime, since I did that already. Unfortunately I lost that sourcecode (I overwrote it by accident) and now I don't remember what did. Must have been something trivial I guess. Some parameter of FillMusicBuffer() maybe? I appreciate any help.
Code: Select all
ampx=10
ampx=10
bla=False
mtoggle=True
noise={2500}
;*** FUNCTIONS ***** FUNCTIONS **** FUNCTIONS **** FUNCTIONS ****
Function p_makenoise()
If mtoggle=True
ampy=1
ampz=1
Box (100, 100, 50, 50, #BLUE)
Else
ampy=0.5
ampz=0.5
Box (100, 100, 50, 50, #RED)
EndIf
For k=0 To 2500
noise[k]=Sin(k/ampx)*60*Ampz+Cos(k/ampy/2)*60*Ampz
Next
CreateSample(1, noise, 10000)
bla=1
EndFunction
Function p_dobutton1()
mtoggle= ~mtoggle
p_makenoise()
EndFunction
Function p_FillMusicBuffer()
If bla >0
FillMusicBuffer (1, "sample", 2500, {id=1} )
Else
FillMusicBuffer(1, "Mute", 500)
EndIf
EndFunction
Box (100, 100, 50, 50, #RED)
evtmatch1={ OnMouseUp = p_dobutton1 }
MakeButton (1, #SIMPLEBUTTON,100, 100, 50, 50, evtmatch1)
InstallEventHandler({FillMusicBuffer = p_FillMusicBuffer} )
CreateMusic (1, 10000, #MONO8)
PlayMusic (1)
Re: gapless sample replay - how to do?
Posted: Fri Apr 27, 2012 1:58 pm
by airsoftsoftwair
The delay is caused by the internal buffering. I don't think there's currently a way around this so I'm wondering how you did achieve the realtime changes? Maybe it is possible to feed only very few samples to
FillMusicBuffer(), i.e. less than requested. But I'm not sure if this will work at all.
I'll think about how this problem could be worked around more elegantly for the next update.
Re: gapless sample replay - how to do?
Posted: Fri Apr 27, 2012 3:58 pm
by zylesea
Andreas wrote:The delay is caused by the internal buffering. I don't think there's currently a way around this so I'm wondering how you did achieve the realtime changes? Maybe it is possible to feed only very few samples to FillMusicBuffer(), i.e. less than requested. But I'm not sure if this will work at all.
I'll think about how this problem could be worked around more elegantly for the next update.
Thanks for the reply. It's really a pity that I lost that sourcecode (I overwrote the actual file by accident with an empty one before I made a back up copy of that. Then left the project for a few weeks and forgot what I actually did.
I still have the binaries (win/morphos) at
http://via.i-networx.de/Simephys/about.htm though - the sound there is in sync with the oscilloscope and more or less real time. I am rather sure my source to feed FillMusicBuffer was not very small, but held enough data for 1/4 or 1/8 of a second.
I think some circular buffer for audio streams would be cool. You don't need to wait for flushing or terminating the buffer when writing new content. However, I don't know how that could work without pointers.
Gosh, if I only knew how I did it a few weeks ago...
Re: gapless sample replay - how to do?
Posted: Tue May 08, 2012 11:38 am
by zylesea
Last night I remembered my trick. I actually kind of cheated: The sound I need is a continous and rather random background plus some temporal precise events. Since backgrund and these events aren't temporally tightly coupled I just splitted them. I did a gapless replay of the background (with the buffer delay) and played single samples directly on top of that. Works!