gaudio

package module
v0.0.0-...-b3d4d34 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2022 License: BSL-1.0 Imports: 21 Imported by: 0

README

Gaudio

Pure Go audio library with a simple and easy to use API (inspired by pydub)

import "github.com/zeozeozeo/gaudio"

Supported formats

Audio formats:

Tracker formats:

Examples

Create a segment from path

import (
    "github.com/zeozeozeo/gaudio"
)

// Create a segment from path (see supported formats)
segment, err := gaudio.LoadAudioFromPath("audio.mp3", gaudio.FormatMP3)
if err != nil {
    panic(err)
}

Create a segment from a reader

// Open file
file, err := os.Open("song.mp3")
if err != nil {
    panic(err)
}
defer file.Close()

// Create a segment (see supported formats)
segment, err := gaudio.LoadAudio(file, gaudio.FormatMP3)
if err != nil {
    panic(err)
}

Overlay segment2 over segment1 at the 3rd second

segment1.Overlay(segment2, 3)

Clone a segment

clone := segment.Clone()

Concatenate segments

// Concatenate segment at the start of another segment
segment1.ConcatenateStart(segment2)

// Concatenate segment at the end of another segment
segment1.ConcatenateEnd(segment2)

// Concatenate segment at the specified second of another segment (3.5th second)
segment1.ConcatenateAtSecond(segment2, 3.5)

Detect and remove silence

threshold = 0.01 // Silence threshold

// Get leading and trailing silence
leading, trailing := segment.DetectSilence(threshold)

// Get leading silence
leading := segment.DetectSilenceStart(threshold)

// Get trailing silence
trailing := segment.DetectSilenceEnd(threshold)

// Remove silence
segment.RemoveStartAndEndSilence(threshold)
segment.RemoveStartSilence(threshold)
segment.RemoveEndSilence(threshold)

Calculate BPM (warning: can be slow)

// minBpm: the minimum BPM you expect (120)
// maxBpm: the maximum BPM you expect (200)
// steps: the amount of steps per interval (1024)
// samplesPerBeat: the amount of samples used for a single beat (1024)
bpm := segment.CalcBPM(120, 200, 1024, 1024)

Apply echo effect

// delay: delay between echo layers (0.05)
// layers: amount of layer (2)
segment.EchoEffect(0.05, 2)

Pitch to note note (needs testing)

// Pitch formula: 2 ** (key / 12)
segment.ApplyNote(12)

Export a segment to a file (only wav files are supported right now)

file, err := os.Create("output.wav")
if err != nil {
    panic(err)
}
defer file.Close()

segment.Export(file, gaudio.FormatWAVE)

Apply fade in / fade out effect

// start float64: the amount of fade-in seconds
// end float64: the amount of fade-out seconds
segment.Fade(0.5, 1) // Fade in for 0.5 seconds, fade out for 1 second

// This is equal to...
segment.FadeIn(0.5)
segment.FadeOut(1)

Invert phase

segment.InvertPhase()

Reverse

segment.Reverse()

Repeat segment n times

segment.Repeat(5)

Change speed (speedup, slowdown)

// Change speed by two times
segment.SetSpeed(2)

// Slow down
segment.SetSpeed(0.25)

Take a slice out of a segment

// Take a slice from the 1st second to the 2nd second (the length of the slice will be 1 second)
slice := segment.Slice(1, 2)

Trim (cut)

// Remove everything between the first second and the 1.5th second
segment.Trim(1, 1.5)

// Remove first 3 seconds
segment.TrimStart(3)

// Remove last 2.3 seconds
segment.TrimEnd(2.3)

Empty segment

// Sample rate, channels
gaudio.Empty(44100, 2)

Silent segment

// Returns a silent segment with the length of 5.5 seconds, 44100 sample rate, and two channels
gaudio.Silent(5.5, 44100, 2)

Raw data

Raw data is stored in float32 in segment.Data, and is structured like that:

[channel 1 value, channel 2 value, channel 1 value, channel 2 value, ...]

Audio formats

const (
	FormatFLAC AudioFormat = 1 // .flac
	FormatWAVE AudioFormat = 2 // .wav
	FormatMP3  AudioFormat = 3 // .mp3
	FormatRAW  AudioFormat = 4 // Custom format

	// Tracker formats
	FormatMOD          AudioFormat = 5 // ProTracker .mod, rendered with gomodplay. This is faster than gotracker, but less accurate.
	FormatGotrackerMod AudioFormat = 6 // ProTracker .mod, rendered with Gotracker. This is slower than gomodplay, but more accurate.
	FormatS3M          AudioFormat = 7 // ScreamTracker III .s3m, rendered with Gotracker
	FormatXM           AudioFormat = 8 // FastTracker II .xm, rendered with Gotracker
	FormatIT           AudioFormat = 9 // ImpulseTracker .it, rendered with Gotracker
)

TODO

  • Tests, benchmarks, profiling
  • Fix speed being rounded up to integers
  • More effects
  • Support more formats (while staying 100% Go)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConvertSampleRate

func ConvertSampleRate(segment *Segment, want uint64) ([]float32, error)

Convert the sample rate of the segment.

func FakeReadSeeker

func FakeReadSeeker(initial []byte) fileBuffer

Creates new buffer that implements io.ReadWriteSeeker.

func GetFormatString

func GetFormatString(format AudioFormat) string

Types

type AudioFormat

type AudioFormat int
const (
	FormatFLAC AudioFormat = 1 // .flac
	FormatWAVE AudioFormat = 2 // .wav
	FormatMP3  AudioFormat = 3 // .mp3
	FormatRAW  AudioFormat = 4 // Custom format

	// Tracker formats
	FormatMOD          AudioFormat = 5 // ProTracker .mod, rendered with gomodplay. This is faster than gotracker, but less accurate.
	FormatGotrackerMod AudioFormat = 6 // ProTracker .mod, rendered with Gotracker. This is slower than gomodplay, but more accurate.
	FormatS3M          AudioFormat = 7 // ScreamTracker III .s3m, rendered with Gotracker
	FormatXM           AudioFormat = 8 // FastTracker II .xm, rendered with Gotracker
	FormatIT           AudioFormat = 9 // ImpulseTracker .it, rendered with Gotracker
)

type Segment

type Segment struct {
	Data          []float32
	Channels      int     // Amount of channels (will be 2, even if there is one)
	SampleRate    uint64  // The sample rate of the segment
	Length        uint64  // Length of the segment in samples
	LengthSeconds float64 // Length of the segment in seconds
	Format        AudioFormat
}

func Empty

func Empty(sampleRate uint64, channels uint) *Segment

Returns an empty segment.

func LoadAudio

func LoadAudio(reader io.Reader, format AudioFormat) (*Segment, error)

Loads an audio file from a reader.

func LoadAudioFromPath

func LoadAudioFromPath(path string, format AudioFormat) (*Segment, error)

Loads an audio file from the file path.

func SegmentFromData

func SegmentFromData(data []float32, channels int, sampleRate uint64) *Segment

Converts a float32 array to a Segment. Structure of the audio array values (assume you have 2 channels): [channel 1 val, channel 2 val, channel 1 val, channel 2 val, ...]

func Silent

func Silent(seconds float64, sampleRate uint64, channels uint) *Segment

Returns a silent segment, with the length of n seconds.

func (*Segment) ApplyNote

func (segment *Segment) ApplyNote(key int)

Pitches audio down to the note. Pitch formula: 2 ** (key / 12). This will change the sample rate.

func (*Segment) CalcBPM

func (segment *Segment) CalcBPM(minBpm float64, maxBpm float64, steps float64, samplesPerBeat uint64) float64

Calculates the BPM of this segment. Warning: this is very slow (and inaccurate), and even slower for bigger segments. Use a smaller slice of a segment instead of the entire thing to get faster results. minBpm: the minimum BPM you expect (120) maxBpm: the maximum BPM you expect (200) steps: the amount of steps per interval (1024) samplesPerBeat: the amount of samples used for a single beat (1024) Returns the calculated BPM value

func (*Segment) Clone

func (segment *Segment) Clone() *Segment

Returns a copy of this segment.

func (*Segment) ConcatenateAt

func (segment *Segment) ConcatenateAt(segment2 *Segment, index uint64) error

Concatenate a segment at a specified index

func (*Segment) ConcatenateAtSecond

func (segment *Segment) ConcatenateAtSecond(segment2 *Segment, second float64)

func (*Segment) ConcatenateEnd

func (segment *Segment) ConcatenateEnd(segment2 *Segment) error

Concatenate a segment at the end

func (*Segment) ConcatenateStart

func (segment *Segment) ConcatenateStart(segment2 *Segment) error

Concatenate a segment at the start

func (*Segment) ConvertChannels

func (segment *Segment) ConvertChannels(channels int)

func (*Segment) DetectSilence

func (segment *Segment) DetectSilence(threshold float32) (float64, float64)

Detect silence (volume <= threshold) in audio. Returns the amount of silence from the start and the end (in seconds). Volume ranges from 0 to 1.

func (*Segment) DetectSilenceEnd

func (segment *Segment) DetectSilenceEnd(threshold float32) float64

Detect trailing silence (volume <= threshold) in seconds

func (*Segment) DetectSilenceStart

func (segment *Segment) DetectSilenceStart(threshold float32) float64

Detect starting silence (volume <= threshold) in audio in seconds

func (*Segment) EchoEffect

func (segment *Segment) EchoEffect(delay float64, layers int)

Applies an echo effect on the segment. delay: delay between echo layers (0.05) layers: amount of layer (2)

func (*Segment) Export

func (segment *Segment) Export(writer io.Writer, format AudioFormat) error

func (*Segment) Fade

func (segment *Segment) Fade(start float64, end float64)

Fade in/out effect. start float64: the amount of fade-in seconds end float64: the amount of fade-out seconds

func (*Segment) FadeIn

func (segment *Segment) FadeIn(seconds float64)

Fade in effect. Use Segment.Fade if you want both fade in and out.

func (*Segment) FadeOut

func (segment *Segment) FadeOut(seconds float64)

Fade out effect. Use Segment.Fade if you want both fade in and out.

func (*Segment) GetIndexAtTime

func (segment *Segment) GetIndexAtTime(time float64) uint64

Returns the index of the specified second in segment.Data If the index is bigger than the segment length, returns the last index.

func (*Segment) GetMaxAbsValue

func (segment *Segment) GetMaxAbsValue() float32

Get the maximum (absolute) value of the segment.

func (*Segment) InvertPhase

func (segment *Segment) InvertPhase()

Inverts the phase of this segment

func (*Segment) Normalize

func (segment *Segment) Normalize()

Normalizes audio values of this segment from -1.0 to 1.0.

func (*Segment) Overlay

func (segment *Segment) Overlay(segment2 *Segment, start float64) error

Overlay one segment on top of another. segment2 *gaudio.Segment: The segment you want to overlay. start float64: The second you want to overlay the segment at. This will automatically normalize the audio to avoid clipping. If the length of the overlayed segment is bigger, the second second will be cropped to the size of the target segment.

func (*Segment) RemoveEndSilence

func (segment *Segment) RemoveEndSilence(threshold float32)

Removes the trailing silence (volume <= threshold) from the segment

func (*Segment) RemoveStartAndEndSilence

func (segment *Segment) RemoveStartAndEndSilence(threshold float32)

Removes all silence (volume <= threshold) from the segment

func (*Segment) RemoveStartSilence

func (segment *Segment) RemoveStartSilence(threshold float32)

Removes the starting silence (volume <= threshold) from the segment

func (*Segment) Repeat

func (segment *Segment) Repeat(amount uint) error

Repeats the segment n times

func (*Segment) Reverse

func (segment *Segment) Reverse()

Reverses this segment.

func (*Segment) SamplesToSeconds

func (segment *Segment) SamplesToSeconds(index uint64) float64

func (*Segment) SetSpeed

func (segment *Segment) SetSpeed(speed float64)

func (*Segment) Slice

func (segment *Segment) Slice(start float64, end float64) *Segment

Takes a slice out of this segment, and returns a new segment. start: the start of the slice in seconds end: the end of the slice in seconds

func (*Segment) SlowDown

func (segment *Segment) SlowDown(speed float64)

Slows down the segment by changing the sample rate.

func (*Segment) SpeedUp

func (segment *Segment) SpeedUp(speed float64)

Speeds up the segment by n times without changing the sample rate. Currently this rounds up speeds to integers (read fixme).

func (*Segment) Trim

func (segment *Segment) Trim(start float64, end float64)

Removes everything between start..end from this segment (in seconds)

func (*Segment) TrimEnd

func (segment *Segment) TrimEnd(seconds float64)

Removs n seconds from the end of the segment

func (*Segment) TrimStart

func (segment *Segment) TrimStart(seconds float64)

Removes n seconds from the start of the segment

func (*Segment) UpdateLength

func (segment *Segment) UpdateLength()

Updates .Length and .LengthSeconds of the segment. Call after modifying the length of segment.Data.

Jump to

Keyboard shortcuts

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