#dsp #audio #audio-conversion #conversion

audio_sample

A library for working with audio samples

1 stable release

Uses new Rust 2024

new 1.0.0 Mar 24, 2025

#203 in #dsp

MIT license

99KB
503 lines

Audio Sample Conversion Library

This crate provides functionality for working with audio samples and converting between different audio sample formats. It focuses on correctness, performance, and ease of use.

Supported Sample Types

  • i16: 16-bit signed integer samples - Common in WAV files and CD-quality audio
  • i24: 24-bit signed integer samples - From the [i24] crate. In-between PCM_16 and PCM_32 in terms of quality and space on disk.
  • i32: 32-bit signed integer samples (high-resolution audio)
  • f32: 32-bit floating point samples (common in audio processing)
  • f64: 64-bit floating point samples (high-precision audio processing)

Features

  • Type Safety: Using Rust's type system to ensure correct conversions
  • High Performance: Simple code that enables the compiler to produce fast code. The [AudioSample] trait simply enables working with some primitives within the context of audio processing - floats between -1.0 and 1.0 etc.

Usage Examples

Basic Sample Conversion

use audio_sample::{AudioSample, ConvertTo};

// Convert an i16 sample to floating point
let i16_sample: i16 = i16::MAX / 2; // 50% of max amplitude
let f32_sample: f32 = i16_sample.convert_to();
assert!((f32_sample - 0.5).abs() < 0.0001);

// Convert a floating point sample to i16
let f32_sample: f32 = -0.75;
let i16_sample: i16 = f32_sample.convert_to();
assert_eq!(i16_sample, -24575); // -75% of max amplitude

Converting Buffers of Samples

use audio_sample::ConvertSequence;

// Using ConvertSlice trait for Box<[T]>
let i16_buffer: Box<[i16]> = vec![0, 16384, -16384, 32767].into_boxed_slice();
let f32_buffer: Box<[f32]> = i16_buffer.convert_sequence();

Implementation Details

Integer Scaling

When converting between integer formats of different bit depths:

  • Widening conversions (e.g., i16 to i32): The samples are shifted left to preserve amplitude.
  • Narrowing conversions (e.g., i32 to i16): The samples are shifted right, which may lose precision.

Float to Integer Conversion

  • Floating-point samples are assumed to be in the range -1.0 to 1.0.
  • They are scaled to the full range of the target integer type.
  • Values are rounded to the nearest integer rather than truncated.
  • Values outside the target range are clamped to prevent overflow.

Integer to Float Conversion

  • Integer samples are scaled to the range -1.0 to 1.0.
  • The maximum positive integer value maps to 1.0.
  • The minimum negative integer value maps to -1.0.

Bugs / Issues

Report them on the Github Page and I will try and get to it as soon as I can :)

Benchmarks

f32 to i32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f32 i32 1 8000 1 6556 6561.2 6566.6 µs
f32 i32 1 16000 1 13116 13137 13161 µs
f32 i32 1 44100 1 36304 36720 37219 µs
f32 i32 10 8000 1 65400 65670 66022 µs
f32 i32 10 16000 1 132230 132560 133000 µs
f32 i32 10 44100 1 392190 396800 401890 µs
f32 i32 60 8000 1 427200 432810 439250 µs
f32 i32 60 16000 1 900970 902350 904090 µs
f32 i32 60 44100 1 2.56e+06 2.588e+06 2.6202e+06 ms

f32 to i24

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f32 i24 1 8000 1 6134.1 6139.9 6145.6 µs
f32 i24 1 16000 1 12251 12405 12611 µs
f32 i24 1 44100 1 33754 34128 34591 µs
f32 i24 10 8000 1 60847 60992 61148 µs
f32 i24 10 16000 1 122800 123210 123710 µs
f32 i24 10 44100 1 364650 372240 380700 µs
f32 i24 60 8000 1 395880 398620 402870 µs
f32 i24 60 16000 1 791120 796520 804890 µs
f32 i24 60 44100 1 2.3384e+06 2.3628e+06 2.3922e+06 ms

i16 to f64

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i16 f64 1 8000 1 0.18952 0.18977 0.19004 ps
i16 f64 1 16000 1 0.18964 0.18991 0.19019 ps
i16 f64 1 44100 1 0.18934 0.18978 0.19026 ps
i16 f64 10 8000 1 0.1895 0.18974 0.18999 ps
i16 f64 10 16000 1 0.1892 0.1895 0.18981 ps
i16 f64 10 44100 1 0.18814 0.18832 0.1885 ps
i16 f64 60 8000 1 0.18944 0.18966 0.18989 ps
i16 f64 60 16000 1 0.18903 0.18924 0.18946 ps
i16 f64 60 44100 1 0.18907 0.18922 0.18939 ps

f32 to f64

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f32 f64 1 8000 1 1550.2 1552.2 1554.3 µs
f32 f64 1 16000 1 2956.2 2959.9 2963.8 µs
f32 f64 1 44100 1 7894.1 7903.3 7913.5 µs
f32 f64 10 8000 1 14396 14504 14597 µs
f32 f64 10 16000 1 37054 37331 37622 µs
f32 f64 10 44100 1 153370 154160 154970 µs
f32 f64 60 8000 1 164240 165400 166430 µs
f32 f64 60 16000 1 322160 324870 327690 µs
f32 f64 60 44100 1 1.6129e+06 1.6407e+06 1.6735e+06 ms

i16 to i32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i16 i32 1 8000 1 0.18946 0.18971 0.18996 ps
i16 i32 1 16000 1 0.18965 0.18992 0.19023 ps
i16 i32 1 44100 1 0.18876 0.18899 0.18922 ps
i16 i32 10 8000 1 0.18915 0.18938 0.18962 ps
i16 i32 10 16000 1 0.18885 0.18904 0.18924 ps
i16 i32 10 44100 1 0.19002 0.19027 0.19049 ps
i16 i32 60 8000 1 0.18891 0.18906 0.18921 ps
i16 i32 60 16000 1 0.189 0.18921 0.18943 ps
i16 i32 60 44100 1 0.18934 0.18958 0.1898 ps

i16 to i24

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i16 i24 1 8000 1 0.18923 0.18965 0.1901 ps
i16 i24 1 16000 1 0.19057 0.19093 0.1913 ps
i16 i24 1 44100 1 0.18862 0.18908 0.18961 ps
i16 i24 10 8000 1 0.19038 0.19068 0.19097 ps
i16 i24 10 16000 1 0.18884 0.18923 0.18966 ps
i16 i24 10 44100 1 0.18975 0.19007 0.19036 ps
i16 i24 60 8000 1 0.19056 0.19084 0.19116 ps
i16 i24 60 16000 1 0.19053 0.19087 0.19134 ps
i16 i24 60 44100 1 0.18925 0.18945 0.18966 ps

f64 to i32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f64 i32 1 8000 1 0.1895 0.18973 0.18994 ps
f64 i32 1 16000 1 0.18913 0.18941 0.18967 ps
f64 i32 1 44100 1 0.18996 0.19026 0.19058 ps
f64 i32 10 8000 1 0.18778 0.18803 0.18832 ps
f64 i32 10 16000 1 0.18704 0.18708 0.18714 ps
f64 i32 10 44100 1 0.18704 0.18708 0.18714 ps
f64 i32 60 8000 1 0.18705 0.1871 0.18715 ps
f64 i32 60 16000 1 0.18703 0.18704 0.18705 ps
f64 i32 60 44100 1 0.18703 0.18705 0.18708 ps

i32 to f32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i32 f32 1 8000 1 0.18898 0.1893 0.18965 ps
i32 f32 1 16000 1 0.18902 0.18925 0.1895 ps
i32 f32 1 44100 1 0.1894 0.18965 0.18989 ps
i32 f32 10 8000 1 0.1899 0.19016 0.19042 ps
i32 f32 10 16000 1 0.18985 0.1901 0.19032 ps
i32 f32 10 44100 1 0.18955 0.1898 0.19003 ps
i32 f32 60 8000 1 0.1896 0.18986 0.19014 ps
i32 f32 60 16000 1 0.18976 0.19002 0.19028 ps
i32 f32 60 44100 1 0.19002 0.19027 0.19051 ps

f32 to i16

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f32 i16 1 8000 1 626.49 627.03 627.57 ns
f32 i16 1 16000 1 1272.2 1274 1275.7 µs
f32 i16 1 44100 1 3484.5 3492.7 3501.6 µs
f32 i16 10 8000 1 6336.5 6349 6362.4 µs
f32 i16 10 16000 1 12731 12762 12806 µs
f32 i16 10 44100 1 60122 60320 60550 µs
f32 i16 60 8000 1 66239 66411 66575 µs
f32 i16 60 16000 1 134110 134540 135050 µs
f32 i16 60 44100 1 403660 407690 412350 µs

i24 to f32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i24 f32 1 8000 1 0.19026 0.19048 0.19068 ps
i24 f32 1 16000 1 0.18973 0.18991 0.19007 ps
i24 f32 1 44100 1 0.18979 0.19007 0.19036 ps
i24 f32 10 8000 1 0.18978 0.18996 0.19013 ps
i24 f32 10 16000 1 0.19024 0.19044 0.19062 ps
i24 f32 10 44100 1 0.1904 0.1905 0.19058 ps
i24 f32 60 8000 1 0.18882 0.18911 0.18942 ps
i24 f32 60 16000 1 0.18962 0.18979 0.18997 ps
i24 f32 60 44100 1 0.19027 0.19049 0.19072 ps

i24 to f64

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i24 f64 1 8000 1 0.1891 0.18933 0.18955 ps
i24 f64 1 16000 1 0.1896 0.18993 0.19031 ps
i24 f64 1 44100 1 0.18989 0.19009 0.19032 ps
i24 f64 10 8000 1 0.1891 0.1894 0.18976 ps
i24 f64 10 16000 1 0.18967 0.18992 0.19019 ps
i24 f64 10 44100 1 0.18943 0.18967 0.18989 ps
i24 f64 60 8000 1 0.18968 0.18995 0.19025 ps
i24 f64 60 16000 1 0.18934 0.18953 0.18974 ps
i24 f64 60 44100 1 0.1899 0.19011 0.19031 ps

i32 to i24

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i32 i24 1 8000 1 0.18948 0.18977 0.19007 ps
i32 i24 1 16000 1 0.18972 0.18994 0.19017 ps
i32 i24 1 44100 1 0.18985 0.19008 0.19035 ps
i32 i24 10 8000 1 0.18929 0.18958 0.18989 ps
i32 i24 10 16000 1 0.18894 0.18931 0.18972 ps
i32 i24 10 44100 1 0.18961 0.18995 0.19028 ps
i32 i24 60 8000 1 0.18967 0.18988 0.1901 ps
i32 i24 60 16000 1 0.18984 0.19005 0.19025 ps
i32 i24 60 44100 1 0.18973 0.19025 0.19095 ps

i32 to i16

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i32 i16 1 8000 1 0.19027 0.1906 0.19098 ps
i32 i16 1 16000 1 0.18973 0.19006 0.19036 ps
i32 i16 1 44100 1 0.19002 0.19032 0.19058 ps
i32 i16 10 8000 1 0.18962 0.18992 0.19022 ps
i32 i16 10 16000 1 0.18996 0.19021 0.19044 ps
i32 i16 10 44100 1 0.18941 0.18969 0.19 ps
i32 i16 60 8000 1 0.18892 0.18916 0.18941 ps
i32 i16 60 16000 1 0.18982 0.19008 0.19034 ps
i32 i16 60 44100 1 0.18916 0.18939 0.18962 ps

f64 to i16

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f64 i16 1 8000 1 0.18981 0.1901 0.19042 ps
f64 i16 1 16000 1 0.18948 0.18969 0.1899 ps
f64 i16 1 44100 1 0.18963 0.18984 0.19004 ps
f64 i16 10 8000 1 0.18958 0.18985 0.19013 ps
f64 i16 10 16000 1 0.18968 0.18999 0.19031 ps
f64 i16 10 44100 1 0.18943 0.1897 0.18998 ps
f64 i16 60 8000 1 0.18937 0.18959 0.1899 ps
f64 i16 60 16000 1 0.18895 0.18907 0.1892 ps
f64 i16 60 44100 1 0.18925 0.18948 0.18969 ps

i24 to i32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i24 i32 1 8000 1 0.19061 0.19082 0.191 ps
i24 i32 1 16000 1 0.19098 0.1911 0.19126 ps
i24 i32 1 44100 1 0.19023 0.19043 0.19062 ps
i24 i32 10 8000 1 0.18904 0.1893 0.18957 ps
i24 i32 10 16000 1 0.19026 0.19055 0.1908 ps
i24 i32 10 44100 1 0.19065 0.1908 0.19094 ps
i24 i32 60 8000 1 0.19022 0.19047 0.19073 ps
i24 i32 60 16000 1 0.18957 0.18984 0.19011 ps
i24 i32 60 44100 1 0.18993 0.19014 0.19037 ps

i16 to f32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i16 f32 1 8000 1 0.19042 0.19067 0.19091 ps
i16 f32 1 16000 1 0.18899 0.18934 0.18974 ps
i16 f32 1 44100 1 0.18899 0.18915 0.18931 ps
i16 f32 10 8000 1 0.18846 0.18868 0.18893 ps
i16 f32 10 16000 1 0.18963 0.18984 0.19004 ps
i16 f32 10 44100 1 0.18982 0.19004 0.19026 ps
i16 f32 60 8000 1 0.18947 0.18963 0.18978 ps
i16 f32 60 16000 1 0.18972 0.18991 0.1901 ps
i16 f32 60 44100 1 0.1886 0.18872 0.18885 ps

i24 to i16

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i24 i16 1 8000 1 0.18868 0.18884 0.18901 ps
i24 i16 1 16000 1 0.18883 0.18904 0.18924 ps
i24 i16 1 44100 1 0.18864 0.18896 0.18933 ps
i24 i16 10 8000 1 0.19047 0.19068 0.1909 ps
i24 i16 10 16000 1 0.19135 0.19141 0.19146 ps
i24 i16 10 44100 1 0.19071 0.19082 0.191 ps
i24 i16 60 8000 1 0.19033 0.19063 0.19094 ps
i24 i16 60 16000 1 0.1898 0.19006 0.19034 ps
i24 i16 60 44100 1 0.18996 0.19021 0.19045 ps

f64 to f32

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f64 f32 1 8000 1 0.18705 0.18709 0.18716 ps
f64 f32 1 16000 1 0.18705 0.18708 0.18712 ps
f64 f32 1 44100 1 0.18704 0.18705 0.18707 ps
f64 f32 10 8000 1 0.18703 0.18704 0.18705 ps
f64 f32 10 16000 1 0.18705 0.18708 0.1871 ps
f64 f32 10 44100 1 0.18704 0.18705 0.18706 ps
f64 f32 60 8000 1 0.18713 0.18717 0.18721 ps
f64 f32 60 16000 1 0.18703 0.18705 0.18707 ps
f64 f32 60 44100 1 0.18926 0.18967 0.1901 ps

f64 to i24

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
f64 i24 1 8000 1 0.18999 0.19022 0.19046 ps
f64 i24 1 16000 1 0.18906 0.18931 0.18956 ps
f64 i24 1 44100 1 0.18961 0.18991 0.19026 ps
f64 i24 10 8000 1 0.18986 0.19013 0.19041 ps
f64 i24 10 16000 1 0.18879 0.18908 0.18947 ps
f64 i24 10 44100 1 0.18926 0.18961 0.19001 ps
f64 i24 60 8000 1 0.18977 0.19001 0.19025 ps
f64 i24 60 16000 1 0.18893 0.18911 0.18931 ps
f64 i24 60 44100 1 0.18973 0.18995 0.19015 ps

i32 to f64

from_type to_type duration_sec sample_rate_hz channels min_time_ns median_time_ns max_time_ns time_unit
i32 f64 1 8000 1 0.1893 0.18954 0.18979 ps
i32 f64 1 16000 1 0.1895 0.18984 0.19016 ps
i32 f64 1 44100 1 0.18996 0.19032 0.19067 ps
i32 f64 10 8000 1 0.18941 0.1896 0.18978 ps
i32 f64 10 16000 1 0.18963 0.19 0.19039 ps
i32 f64 10 44100 1 0.18933 0.18962 0.18999 ps
i32 f64 60 8000 1 0.18931 0.18962 0.18995 ps
i32 f64 60 16000 1 0.18977 0.18996 0.19017 ps
i32 f64 60 44100 1 0.18901 0.18921 0.18941 ps

Dependencies

~0.5–1MB
~20K SLoC