I want to use a slightly changed run method that I have found in the MBS example (PortAudio).
I want to present two sinus sonds with a given duration with a pause between them (the pauses and so on are not the problem, I use timer). After playing a sinus sound I got always something like a stopping “click” in the sound. The sinus sound does not end with silence it ends with something like a “click” or “crack”. Is there a possibility to prevent this (or why does this happens?). Has anyone this problem before and a solution?
At the moment I use XOJO Version 2016 1.1 on my Mac but I also want to use the sinus sound presentation on Windows 7 and the “click”/“crack” is the same there.
This is my currently code:
#pragma StackOverflowChecking false
#pragma DisableAutoWaitCursor
#pragma DisableBackgroundTasks
#pragma DisableBoundsChecking
const delta=0.01000
dim n,c,i as integer
dim f as single
c=FrameCount-1
// calculate all possible outside the for loop
dim fixVal as double = ( 2.0 * 3.14159265358979323846264338327950 / 44100)
// tones.pitch ==> module-Variable e.g. 1000 Hz
System.DebugLog(" pitch=" + Str(tones.pitch))
for i=0 to c
f= tones.sinVolume * sin(timeIndex * fixVal * tones.pitch )
timeIndex=timeIndex+1
outputBuffer.SingleValue(n)=f // left
n=n+4
outputBuffer.SingleValue(n)=f // right
n=n+4
next
Is there a possibility to fade in/fade out the sine wave so that no “click”/“crack” will be heard? Does anyone know how to implement this with the MBS AudioPort functions?
Any help is appreciated. Thank you very much.
Thomas
To ramp down just multiply the signal with linearly decreasing values. something like this placed after your code…
[code]dim rampSamples As integer = 20 //change this to how long of a ramp you want
dim rampStartSample As integer = (c - rampSamples) * 8
dim v As Single
for i = 0 to rampSamples
n = rampStartSample + i * 8
v = 1 - i / rampSamples //v ramps from 1 to 0 as i steps from 0 to rampSamples
outputBuffer.SingleValue(n) = v * outputBuffer.SingleValue(n)
outputBuffer.SingleValue(n+4) = v * outputBuffer.SingleValue(n+4)
next[/code]
I use now the mdCreateWaveData and mdCreateWaveFileData from an example in this forum (tone_generator_hearing_test.xojo_binary_project).
This functions generate a real wav-file and the mdCreateWaveFileData is a implementation of Will Shank, thank you .
Now I can fade in/out the sine wave with a linear function. The extended funtion is below. Differences are that the variable seconds is now a double for lower durations as a second and there some other small adaptions.
Function mdGenWavData(seconds as double) As MemoryBlock
dim wavTime As Double = seconds
// self.sampleRate = 44100
dim wavSampleCount As integer = (self.sampleRate * wavTime) //gen 2 seconds of samples
dim m As new MemoryBlock(wavSampleCount)
// self.twoPi = 6.28318 = 2 * PI
dim timeScale As double = (self.twoPi / self.sampleRate)
dim lastSample As integer = wavSampleCount - 1
dim t As double
dim sinVol as integer = 127
// calculate sine wave for a given time (seconds)
for i As integer = 0 to lastSample
t = i * timeScale
m.UInt8Value(i) = 127 + sinVol * sin(self.frequency * t) // sine
next
// calculation for fade in
// new sinVol for linear fade in as a part of wavSampleCount approxim. 25 ms
dim lowerArr(127*10) as Double
for i as integer = 0 to lowerArr.Ubound
lowerArr(i) = (i/lowerArr.Ubound)
next
// change the first 101 samples into zero
for i as integer = 0 to 100
lowerArr.Insert(0, 0.0)
next
// change the volume for the samples at the beginning of sine wave
for i as integer = 0 to lowerArr.Ubound
m.UInt8Value(i) = ((m.UInt8Value(i) - sinVol) * lowerArr(i)) + sinVol
next i
// use the calculation for fade in here to fade out the last samples
dim idx as integer = -1
for i as Integer = lastSample DownTo lastSample - lowerArr.Ubound
idx = idx + 1
m.UInt8Value(i) = ((m.UInt8Value(i) - sinVol) * lowerArr(idx)) + sinVol
next i
return m
End Function