example

package module
v0.0.0-...-212bbe9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2021 License: MIT Imports: 0 Imported by: 0

Image README

Example

PkgGoDev Go Report Card

This package demonstrates pipe framework in action with various available components. For better explanation see godoc.

Dependencies

To execute all examples you'll need to have next dependencies installed and available in your system:

Image 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)
	}
}

Image Source Files

  • example.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL