-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// demo package simulating a realtime generation and processing. | ||
// Start the example from your terminal and type a letter + enter. | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"log" | ||
"math" | ||
"os" | ||
"os/signal" | ||
|
||
"github.com/go-audio/audio" | ||
"github.com/go-audio/generator" | ||
"github.com/go-audio/transforms" | ||
"github.com/gordonklaus/portaudio" | ||
) | ||
|
||
func main() { | ||
bufferSize := 512 | ||
This comment has been minimized.
Sorry, something went wrong. |
||
buf := &audio.FloatBuffer{ | ||
Data: make([]float64, bufferSize), | ||
Format: audio.FormatMono4410016bLE, | ||
} | ||
currentNote := 440.0 | ||
osc := generator.NewOsc(generator.WaveSine, currentNote, buf.Format.SampleRate) | ||
osc.Amplitude = 1 | ||
|
||
sig := make(chan os.Signal, 1) | ||
signal.Notify(sig, os.Interrupt, os.Kill) | ||
|
||
gainControl := 0.0 | ||
This comment has been minimized.
Sorry, something went wrong. |
||
currentVol := osc.Amplitude | ||
|
||
fmt.Println(`This is a demo, press a key followed by enter, the played note should change. | ||
Use the - and + keys follow by enter to decrease or increase the volume\nPress q or ctrl-c to exit. | ||
Note that the sound will come out of your default sound card.`) | ||
|
||
scanner := bufio.NewScanner(os.Stdin) | ||
go func() { | ||
for scanner.Scan() { | ||
if len(scanner.Text()) > 0 { | ||
k := scanner.Text()[0] | ||
switch k { | ||
case 'q': | ||
sig <- os.Interrupt | ||
case '+': | ||
gainControl += 0.10 | ||
case '-': | ||
gainControl -= 0.10 | ||
This comment has been minimized.
Sorry, something went wrong.
egonelbre
|
||
default: | ||
v := float64(math.Abs(float64(int(k - 100)))) | ||
currentNote = 440.0 * math.Pow(2, (v)/12.0) | ||
fmt.Printf("switching oscillator to %.2f Hz\n", currentNote) | ||
if currentNote > 22000 { | ||
currentNote = 440.0 | ||
} | ||
osc.SetFreq(currentNote) | ||
} | ||
} | ||
} | ||
}() | ||
|
||
// Audio output | ||
portaudio.Initialize() | ||
defer portaudio.Terminate() | ||
out := make([]float32, bufferSize) | ||
stream, err := portaudio.OpenDefaultStream(0, 1, 44100, len(out), &out) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer stream.Close() | ||
|
||
if err := stream.Start(); err != nil { | ||
log.Fatal(err) | ||
} | ||
defer stream.Stop() | ||
for { | ||
|
||
// populate the out buffer | ||
if err := osc.Fill(buf); err != nil { | ||
log.Printf("error filling up the buffer") | ||
} | ||
// apply vol control if needed (applied as a transform instead of a control | ||
// on the osc) | ||
if gainControl != 0 { | ||
currentVol += gainControl | ||
if currentVol < 0.1 { | ||
currentVol = 0 | ||
} | ||
if currentVol > 6 { | ||
currentVol = 6 | ||
} | ||
fmt.Printf("new vol %f.2", currentVol) | ||
gainControl = 0 | ||
} | ||
transforms.Gain(buf, currentVol) | ||
|
||
f64ToF32Copy(buf.Data, out) | ||
|
||
// write to the stream | ||
if err := stream.Write(); err != nil { | ||
This comment has been minimized.
Sorry, something went wrong.
egonelbre
|
||
log.Printf("error writing to stream : %v\n", err) | ||
} | ||
select { | ||
case <-sig: | ||
fmt.Println("\tCiao!") | ||
return | ||
default: | ||
} | ||
} | ||
} | ||
|
||
// portaudio doesn't support float64 so we need to copy our data over to the | ||
// destination buffer. | ||
func f64ToF32Copy(src []float64, dst []float32) { | ||
This comment has been minimized.
Sorry, something went wrong.
nigeltao
|
||
if len(src) > len(dst) { | ||
This comment has been minimized.
Sorry, something went wrong.
nigeltao
|
||
dst = append(dst, make([]float32, len(src)-len(dst))...) | ||
} | ||
for i := 0; i < len(src); i++ { | ||
This comment has been minimized.
Sorry, something went wrong. |
||
dst[i] = float32(src[i]) | ||
} | ||
} |
1 comment
on commit aed9f58
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both comments addressed, thanks
This number should ideally be 64 or 32. (See http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing)
Starting at 64 we can more easily see all the overhead of communication.