Merge pull request #383 from zbednarke/raw-audio-example
Improve raw audio example
This commit is contained in:
commit
28722bb71f
1 changed files with 31 additions and 33 deletions
|
@ -1,71 +1,69 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"time"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "github.com/gen2brain/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxSamples = 22050
|
nSamples = 44000 * 10
|
||||||
maxSamplesPerUpdate = 4096
|
sampleRate = 6000
|
||||||
|
bufferSize = nSamples
|
||||||
|
frequency = 440
|
||||||
|
targetFPS = 240
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rl.InitWindow(800, 450, "raylib [audio] example - raw audio streaming")
|
rl.InitWindow(800, 450, "raylib [audio] example - raw audio streaming")
|
||||||
|
position := rl.NewVector2(0, 0)
|
||||||
|
|
||||||
|
rl.SetAudioStreamBufferSizeDefault(bufferSize)
|
||||||
|
|
||||||
rl.InitAudioDevice()
|
rl.InitAudioDevice()
|
||||||
|
|
||||||
// Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono)
|
// Init raw audio stream (sample rate: <nSamples>, sample size: 32bit-float, channels: 1-mono)
|
||||||
stream := rl.LoadAudioStream(22050, 32, 1)
|
stream := rl.LoadAudioStream(nSamples, 32, 1)
|
||||||
|
|
||||||
//// Fill audio stream with some samples (sine wave)
|
//// Create sine wave to play
|
||||||
data := make([]float32, maxSamples)
|
data := make([]float32, nSamples)
|
||||||
|
|
||||||
for i := 0; i < maxSamples; i++ {
|
for i := 0; i < nSamples; i++ {
|
||||||
data[i] = float32(math.Sin(float64((2*rl.Pi*float32(i))/2) * rl.Deg2rad))
|
t := float32(i) / float32(nSamples)
|
||||||
|
data[i] = float32(math.Sin(float64((2 * rl.Pi * frequency * t))))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: The generated MAX_SAMPLES do not fit to close a perfect loop
|
// NOTE: The buffer can only be updated when it has been processed. Time between buffer processing and next load and causes clipping
|
||||||
// for that reason, there is a clip everytime audio stream is looped
|
|
||||||
rl.PlayAudioStream(stream)
|
rl.PlayAudioStream(stream)
|
||||||
|
|
||||||
totalSamples := int32(maxSamples)
|
startTime := time.Now()
|
||||||
samplesLeft := int32(totalSamples)
|
rl.SetTargetFPS(targetFPS)
|
||||||
|
|
||||||
position := rl.NewVector2(0, 0)
|
|
||||||
|
|
||||||
rl.SetTargetFPS(30)
|
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
// Refill audio stream if required
|
// Refill audio stream if buffer is processed
|
||||||
if rl.IsAudioStreamProcessed(stream) {
|
if rl.IsAudioStreamProcessed(stream) {
|
||||||
numSamples := int32(0)
|
elapsedTime := time.Since(startTime).Seconds()
|
||||||
if samplesLeft >= maxSamplesPerUpdate {
|
currentSampleIndex := int(math.Mod(elapsedTime*float64(sampleRate), float64(nSamples)))
|
||||||
numSamples = maxSamplesPerUpdate
|
nextSampleIndex := currentSampleIndex + bufferSize
|
||||||
|
|
||||||
|
if nextSampleIndex > nSamples {
|
||||||
|
nextSampleIndex = bufferSize - (nSamples - currentSampleIndex)
|
||||||
|
rl.UpdateAudioStream(stream, append(data[currentSampleIndex:], data[:nextSampleIndex]...))
|
||||||
} else {
|
} else {
|
||||||
numSamples = samplesLeft
|
rl.UpdateAudioStream(stream, data[currentSampleIndex:nextSampleIndex])
|
||||||
}
|
|
||||||
|
|
||||||
rl.UpdateAudioStream(stream, data[totalSamples-samplesLeft:])
|
|
||||||
|
|
||||||
samplesLeft -= numSamples
|
|
||||||
|
|
||||||
// Reset samples feeding (loop audio)
|
|
||||||
if samplesLeft <= 0 {
|
|
||||||
samplesLeft = totalSamples
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
|
|
||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
rl.DrawText("SINE WAVE SHOULD BE PLAYING!", 240, 140, 20, rl.LightGray)
|
rl.DrawText(fmt.Sprintf("%d Hz SINE WAVE SHOULD BE PLAYING!", frequency), 200, 140, 20, rl.LightGray)
|
||||||
|
|
||||||
// NOTE: Draw a part of the sine wave (only screen width)
|
// NOTE: Draw a part of the sine wave (only screen width)
|
||||||
for i := 0; i < int(rl.GetScreenWidth()); i++ {
|
for i := 0; i < int(rl.GetScreenWidth()); i++ {
|
||||||
position.X = float32(i)
|
position.X = float32(i)
|
||||||
position.Y = 250 + 50*data[i]
|
position.Y = 250 + 10*data[i*nSamples/int(20*rl.GetScreenWidth())]
|
||||||
|
|
||||||
rl.DrawPixelV(position, rl.Red)
|
rl.DrawPixelV(position, rl.Red)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue