resample

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2025 License: MIT Imports: 10 Imported by: 0

README

Resample

Go Reference Go Report Card cov

Resample is a package for audio resampling in pure Go. Implementation is based on bandlimited interpolation.

Resample's main features are:

  • io.Copy support (uses little RAM, even for GB-sized files)
  • concurrency
  • speed
  • tested precision
  • no C dependencies

Example

See the API documentation on go.dev.

package main

import (
	"github.com/gunter-q12/resample"
	"io"
	"os"
)

func main() {
	input, _ := os.Open("./original.raw")
	output, _ := os.Create("./resampled.raw")

	res, _ := resample.New(output, resample.FormatInt16, 48000, 16000, 2)
	_, _ = io.Copy(res, input)
}

Benchmarks

Precision

Precision test were performed against a resapmpy library that implements the same exact resampling method. Results were used to create precision unit tests and ensure that implementation is correct.

Performance

Each table row has a different number of entries because libraries provide a different number of quality settings. Results are sorted from the lowest quality to the highest.

Downsampling 44100 -> 16000 Hz, 10 Mb file, in seconds

Library
zaf/resample (SOXR) 0.12 0.13 0.14 0.14 0.16
Resample 0.27 0.31 0.38
resampy 1.12 1.4
gomplerate 0.47

Upsampling 44100 -> 16000 Hz, 10 Mb file, in seconds

Library
zaf/resample (SOXR) 0.32 0.37 0.38 0.36 0.43
Resample 0.47 0.7 1.2
resampy 1.43 2.67
gomplerate 1.66

Settings used:

Library
zaf/resample (SOXR) Quick LowQ MediumQ HighQ VeryHighQ
Resample KaiserFastest KaiserFast KaiserBest
resampy kaiser_fast kaiser_best
gomplerate Default

Documentation

Overview

Example (ResamplingFile)
package main

import (
	"github.com/gunter-q12/resample"
	"io"
	"os"
)

func main() {
	input, _ := os.Open("./original.raw")
	output, _ := os.Create("./resampled.raw")

	res, _ := resample.New(output, resample.FormatInt16, 48000, 16000, 2)
	_, _ = io.Copy(res, input)
}
Example (ResamplingSlice)
package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"github.com/gunter-q12/resample"
)

func main() {
	// Convert slice of values into a slice of bytes
	input := []int16{1, 3, 5}
	inputData := new(bytes.Buffer)
	_ = binary.Write(inputData, binary.LittleEndian, input)

	// Resample
	outBuf := new(bytes.Buffer)
	res, _ := resample.New(outBuf, resample.FormatInt16, 1, 2, 1, resample.WithLinearFilter())
	_, _ = res.Write(inputData.Bytes())

	// Convert bytes back to a slice of values
	output := make([]int16, 5)
	_ = binary.Read(outBuf, binary.LittleEndian, output)

	fmt.Println(output)

}
Output:

[1 2 3 4 5]

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Format

type Format int
const (
	FormatInt16 Format = iota
	FormatInt32
	FormatInt64
	FormatFloat32
	FormatFloat64
)

type Option

type Option struct {
	// contains filtered or unexported fields
}

Option is a struct used to configure Resampler.

func WithKaiserBestFilter

func WithKaiserBestFilter() Option

WithKaiserBestFilter function returns option that configures Resampler to use KaiserBestFilter.

Compared to default (Kaiser Fast) filter, KaiserBestFilter provides higher resampling quality in exchange for lower speed and higher memory usage.

func WithKaiserFastFilter

func WithKaiserFastFilter() Option

WithKaiserFastFilter function returns option that configures Resampler to use KaiserFastFilter.

Used by default.

func WithKaiserFastestFilter

func WithKaiserFastestFilter() Option

WithKaiserFastestFilter function returns option that configures Resampler to use KaiserFastestFilter.

Compared to default (Kaiser Fast) filter, KaiserFastestFilter provides higher resampling speed and lower memory usage in exchange for lower quality.

func WithLinearFilter

func WithLinearFilter() Option

WithLinearFilter function returns option that configures Resampler to use linear filter.

This option should be used only for testing purposes because linear filter provides poor resampling quality.

func WithNoMemoization

func WithNoMemoization() Option

WithNoMemoization function returns option that disables memoization in Resampler.

This option should be used when Resampler consumers too much memory. Such behaviour may occur when resampling between sampling rages with a small greatest common divisor (e.g. 9999 and 10000).

Enabling this function slows the resampling progress significantly. Therefore, most users should avoid it and switch used filter instead.

type Resampler

type Resampler struct {
	// contains filtered or unexported fields
}

A Resampler is a struct used for resampling.

func New

func New(outBuffer io.Writer, format Format, inRate, outRate, ch int,
	options ...Option) (*Resampler, error)

New creates a new Resampler.

Calling Resampler.Write and Resampler.ReadFrom methods on the returned Resampler will resample data according to provided format, inRate, outRate and number of channels. Results are written to the io.Writer.

Default filter is KaiserFastFilter, use WithXFilter options to change it. Memoization is enabled by default, use WithNoMemoization function to disable it.

func (*Resampler) ReadFrom

func (r *Resampler) ReadFrom(reader io.Reader) (int64, error)

ReadFrom reads all the data from reader using batching to reduce memory usage.

func (*Resampler) Write

func (r *Resampler) Write(input []byte) (int, error)

Write writes resampled data to an io.Writer provided during a New call.

If Write is called multiple times, the data is appended to the same io.Writer. Note that calling Write on separate parts of the same file may result in imperfect resampling at the boundaries. For large files that do not fit into memory, use io.Copy instead.

Directories

Path Synopsis
cmd
resampler command

Jump to

Keyboard shortcuts

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