Documentation
¶
Overview ¶
Package example provides examples of pipelined framework usage.
Example (Five) ¶
This example demonstrates how to read two .wav files, mix, process them with vst2 plugin and save result as .mp3 file.
NOTE: For simplicity both wav files have same characteristics i.e: sample rate and number of channels. In real life explicit conversion might be needed.
package main
import (
"context"
"log"
"os"
"pipelined.dev/audio"
"pipelined.dev/audio/mp3"
"pipelined.dev/audio/vst2"
"pipelined.dev/audio/wav"
"pipelined.dev/pipe"
)
func main() {
// open first wav input.
inputFile1, err := os.Open("_testdata/sample1.wav")
if err != nil {
log.Fatalf("failed to open first input file: %v", err)
}
defer inputFile1.Close()
// open second wav input.
inputFile2, err := os.Open("_testdata/sample2.wav")
if err != nil {
log.Fatalf("failed to open second input file: %v", err)
}
defer inputFile2.Close()
// create new mixer with 2 channels.
mixer := audio.Mixer{}
// open vst library.
vst, err := vst2.Open("_testdata/Krush.vst")
if err != nil {
log.Fatalf("failed to open vst2 plugin: %v", err)
}
defer vst.Close()
// create output file.
outputFile, err := os.Create("_testdata/out5.mp3")
if err != nil {
log.Fatalf("failed to create output file: %v", err)
}
defer outputFile.Close()
bufferSize := 512
p, err := pipe.New(bufferSize,
// line for mixing first wav file.
pipe.Line{
// wav pump.
Source: wav.Source(inputFile1),
// mixer sink.
Sink: mixer.Sink(),
},
// line for mixing second wav file.
pipe.Line{
// wav pump.
Source: wav.Source(inputFile2),
// mixer sink.
Sink: mixer.Sink(),
},
// line for sinking mp3.
pipe.Line{
// mixer pump.
Source: mixer.Source(),
// vst2 processor.
Processors: pipe.Processors(
vst.Processor(vst2.Host{}).Allocator(nil),
),
Sink: mp3.Sink(
outputFile,
mp3.VBR(0),
mp3.JointStereo,
mp3.DefaultEncodingQuality,
),
},
)
if err != nil {
log.Fatalf("failed to bind lines: %v", err)
}
// execute the pipe with three lines.
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute pipeline: %v", err)
}
}
Example (Four) ¶
This example demonstrates how to read signal from .wav file, compose a track with clips from that file and then sumalteniously save it to new .wav file and play it with portaudio.
package main
import (
"context"
"log"
"os"
"time"
"pipelined.dev/audio"
"pipelined.dev/audio/portaudio"
"pipelined.dev/audio/wav"
"pipelined.dev/pipe"
"pipelined.dev/signal"
)
func main() {
// open input file.
inputFile, err := os.Open("_testdata/sample1.wav")
if err != nil {
log.Fatalf("failed to open input file: %v", err)
}
defer inputFile.Close()
bufferSize := 512
// asset sink.
asset := &audio.Asset{}
// read wav line.
p, err := pipe.New(
bufferSize,
pipe.Line{
Source: wav.Source(inputFile),
Sink: asset.Sink(),
},
)
if err != nil {
log.Fatalf("failed to bind import pipeline: %v", err)
}
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute import pipeline: %v", err)
}
sampleRate := asset.SampleRate()
// track pump.
track := audio.Track{}
// add samples.
track.AddClip(198450, signal.Slice(asset.Signal, 0, sampleRate.Events(1*time.Second)))
track.AddClip(66150, signal.Slice(asset.Signal, sampleRate.Events(1*time.Second), sampleRate.Events(2*time.Second)))
track.AddClip(132300, signal.Slice(asset.Signal, 0, sampleRate.Events(1*time.Second)))
repeater := audio.Repeater{}
// create output file.
outputFile, err := os.Create("_testdata/out4.wav")
if err != nil {
log.Fatalf("failed to create output file: %v", err)
}
defer outputFile.Close()
err = portaudio.Initialize()
if err != nil {
log.Fatalf("failed to init portaudio: %v", err)
}
defer portaudio.Terminate()
device, err := portaudio.DefaultOutputDevice()
if err != nil {
log.Fatalf("failed to get default system device: %v", err)
}
p, err = pipe.New(
bufferSize,
pipe.Line{
Source: track.Source(sampleRate, 0, 0),
Sink: repeater.Sink(),
},
pipe.Line{
Source: repeater.Source(),
Sink: wav.Sink(outputFile, signal.BitDepth16),
},
pipe.Line{
Source: repeater.Source(),
Sink: portaudio.Sink(device),
},
)
if err != nil {
log.Fatalf("failed to bind lines: %v", err)
}
// execute the pipe with three lines.
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute playback and save pipeline: %v", err)
}
}
Example (One) ¶
This example demonstrates how to play .wav file with portaudio.
package main
import (
"context"
"log"
"os"
"pipelined.dev/audio/portaudio"
"pipelined.dev/audio/wav"
"pipelined.dev/pipe"
)
func main() {
bufferSize := 512
// open source wav file.
wavFile, err := os.Open("_testdata/sample1.wav")
if err != nil {
log.Fatalf("failed to open wav file: %v", err)
}
defer wavFile.Close()
err = portaudio.Initialize()
if err != nil {
log.Fatalf("failed to initialize portaudio: %v", err)
}
defer portaudio.Terminate()
device, err := portaudio.DefaultOutputDevice()
if err != nil {
log.Fatalf("failed to get default system device: %v", err)
}
// build pipe with a single line.
p, err := pipe.New(
bufferSize,
pipe.Line{
Source: wav.Source(wavFile),
Sink: portaudio.Sink(device),
},
)
if err != nil {
log.Fatalf("failed to bind pipeline: %v", err)
}
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute pipeline: %v", err)
}
}
Example (Seven) ¶
This example demonstrates how to walk file system and process files depending on audio file format. It converts all mp3 files to 16-bit wav and removes all flac files.
package main
import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"pipelined.dev/audio/fileformat"
"pipelined.dev/audio/mp3"
"pipelined.dev/audio/wav"
"pipelined.dev/pipe"
"pipelined.dev/signal"
)
func main() {
err := filepath.Walk("_testdata", fileformat.Walk(
func(f *fileformat.Format, path string, fi os.FileInfo) error {
switch f {
case fileformat.MP3():
// open mp3 input file
input, err := os.Open(path)
if err != nil {
return err
}
defer input.Close()
// create wav output file
output, err := os.Create(fmt.Sprintf("%s.wav", path))
defer output.Close()
// bind the line
p, err := pipe.New(
512,
pipe.Line{
Source: mp3.Source(input),
Sink: wav.Sink(output, signal.BitDepth16),
},
)
if err != nil {
return err
}
// execute the pipe with single line
return pipe.Wait(p.Start(context.Background()))
case fileformat.FLAC():
// remove flac file
return os.Remove(path)
}
return nil
}, true))
if err != nil {
log.Fatalf("failed to walk: %v", err)
}
}
Example (Six) ¶
This example demonstrates how to cut a clip from .mp3 file and save the result to new .mp3 file.
package main
import (
"context"
"log"
"os"
"time"
"pipelined.dev/audio"
"pipelined.dev/audio/mp3"
"pipelined.dev/pipe"
"pipelined.dev/signal"
)
func main() {
// open source wav file.
mp3File, err := os.Open("_testdata/sample.mp3")
if err != nil {
log.Fatalf("failed to open mp3 file: %v", err)
}
defer mp3File.Close()
// create output file.
outputFile, err := os.Create("_testdata/out6.mp3")
if err != nil {
log.Fatalf("failed to create output file: %v", err)
}
defer outputFile.Close()
// asset to keep mp3 signal.
a := &audio.Asset{}
bufferSize := 512
p, err := pipe.New(
bufferSize,
pipe.Line{
// mp3 pump.
Source: mp3.Source(mp3File),
// asset sink.
Sink: a.Sink(),
},
)
if err != nil {
log.Fatalf("failed to bind asset pipeline: %v", err)
}
// execute pipe with a single line.
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute asset pipeline: %v", err)
}
// get the sample rate of the asset.
// it will be needed to convert duration.
sampleRate := a.SampleRate()
// cut the clip that starts at 1 second and lasts 2.5 seconds.
clip := signal.Slice(
a.Signal,
sampleRate.Events(time.Millisecond*1000),
sampleRate.Events(time.Millisecond*3500),
)
p, err = pipe.New(
bufferSize,
pipe.Line{
// clip source
Source: audio.Source(sampleRate, clip),
// mp3 sink
Sink: mp3.Sink(
outputFile,
mp3.CBR(320),
mp3.JointStereo,
mp3.DefaultEncodingQuality,
),
},
)
if err != nil {
log.Fatalf("failed to bind output pipeline: %v", err)
}
// build pipe with a single line.
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute output pipeline: %v", err)
}
}
Example (Three) ¶
This example demonstrates how to read two .wav files, mix them together and save result to new .wav file.
NOTE: For simplicity both wav files have same characteristics i.e: sample rate and number of channels. In real life explicit conversion might be needed.
package main
import (
"context"
"log"
"os"
"pipelined.dev/audio"
"pipelined.dev/audio/wav"
"pipelined.dev/pipe"
"pipelined.dev/signal"
)
func main() {
// open first wav input.
inputFile1, err := os.Open("_testdata/sample1.wav")
if err != nil {
log.Fatalf("failed to open first input file: %v", err)
}
defer inputFile1.Close()
// open second wav input.
inputFile2, err := os.Open("_testdata/sample2.wav")
if err != nil {
log.Fatalf("failed to open second input file: %v", err)
}
defer inputFile2.Close()
// create output file.
outputFile, err := os.Create("_testdata/out3.wav")
if err != nil {
log.Fatalf("failed to create output file: %v", err)
}
defer outputFile.Close()
// create mixer with 2 channels.
mix := audio.Mixer{}
bufferSize := 512
p, err := pipe.New(
bufferSize,
pipe.Line{
Source: wav.Source(inputFile1),
Sink: mix.Sink(),
},
pipe.Line{
Source: wav.Source(inputFile2),
Sink: mix.Sink(),
},
pipe.Line{
Source: mix.Source(),
Sink: wav.Sink(outputFile, signal.BitDepth16),
},
)
// run the pipeline.
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute pipeline: %v", err)
}
}
Example (Two) ¶
This example demonstrates how to process .wav file with vst2 plugin and write result to a new .wav file.
package main
import (
"context"
"log"
"os"
"pipelined.dev/audio/vst2"
"pipelined.dev/audio/wav"
"pipelined.dev/pipe"
"pipelined.dev/signal"
)
func main() {
// open input file.
inputFile, err := os.Open("_testdata/sample1.wav")
if err != nil {
log.Fatalf("failed to open input file: %v", err)
}
defer inputFile.Close()
// open vst2 library.
vst, err := vst2.Open("_testdata/Krush.vst")
if err != nil {
log.Fatalf("failed to open vst2 plugin: %v", err)
}
defer vst.Close()
// create output file.
outputFile, err := os.Create("_testdata/out2.wav")
if err != nil {
log.Fatalf("failed to create output file: %v", err)
}
defer outputFile.Close()
bufferSize := 512
// build the line.
p, err := pipe.New(bufferSize, pipe.Line{
// wav pump.
Source: wav.Source(inputFile),
// vst2 processor.
Processors: pipe.Processors(
vst.Processor(vst2.Host{}).Allocator(nil),
),
// wav sink.
Sink: wav.Sink(outputFile, signal.BitDepth16),
})
if err != nil {
log.Fatalf("failed to bind line: %v", err)
}
// run the pipe with a single line.
err = pipe.Wait(p.Start(context.Background()))
if err != nil {
log.Fatalf("failed to execute pipeline: %v", err)
}
}
Source Files
¶
- example.go