All Projects → Sciss → AudioFile

Sciss / AudioFile

Licence: AGPL-3.0 License
Audiofile library for Scala.

Programming Languages

scala
5932 projects
shell
77523 projects

Projects that are alternatives of or similar to AudioFile

mt762x-wm8960
MT762X WM8960 ALSA SoC machine driver
Stars: ✭ 19 (-5%)
Mutual labels:  sound
Eisenkraut
A multi-channel and hi-res capable audio file editor.
Stars: ✭ 50 (+150%)
Mutual labels:  sound
useAudioPlayer
Custom React hook & context for controlling browser audio
Stars: ✭ 176 (+780%)
Mutual labels:  sound
zero-noise
A lightweight multicolor noise generator for sound masking
Stars: ✭ 23 (+15%)
Mutual labels:  sound
roover
🐱 A lightweight audio library for React apps.
Stars: ✭ 70 (+250%)
Mutual labels:  sound
jsfxr
JavaScript sound effects generator.
Stars: ✭ 120 (+500%)
Mutual labels:  sound
reverb
Straightforward (sound/multipurpose) reverberator
Stars: ✭ 23 (+15%)
Mutual labels:  sound
DMXOPL
YMF262-enhanced FM patch set for Doom and source ports.
Stars: ✭ 42 (+110%)
Mutual labels:  sound
Mezzanine
A game engine that supports high performance 3d graphics physics and sound
Stars: ✭ 18 (-10%)
Mutual labels:  sound
ac-audio-extractor
Audio Commons Audio Extractor
Stars: ✭ 33 (+65%)
Mutual labels:  sound
lisp-gui-examples
GUI for generating a tone in various Lisp dialects
Stars: ✭ 28 (+40%)
Mutual labels:  sound
soube
Music player based on electronjs
Stars: ✭ 32 (+60%)
Mutual labels:  sound
debeat
Sound Library for the Defold Engine
Stars: ✭ 20 (+0%)
Mutual labels:  sound
glicol
(Audio) graph-oriented live coding language and music DSP library written in Rust
Stars: ✭ 853 (+4165%)
Mutual labels:  sound
opendev
OpenDev is a non-profit project that tries to collect as many resources (assets) of free use for the development of video games and applications.
Stars: ✭ 34 (+70%)
Mutual labels:  sound
audio-playback
Ruby/Command Line Audio File Player
Stars: ✭ 20 (+0%)
Mutual labels:  sound
aura
A fast and lightweight 3D audio engine for Kha.
Stars: ✭ 31 (+55%)
Mutual labels:  sound
Simple-Unity-Audio-Manager
A decentralized audio playing system for Unity, designed for simplicity and built to scale!
Stars: ✭ 100 (+400%)
Mutual labels:  sound
PdWebParty
An app that allows Pd users to run patches in a web browser and share them with a web link
Stars: ✭ 37 (+85%)
Mutual labels:  sound
uBraids SE
8HP Eurorack module | Voltage-controlled digital oscillator
Stars: ✭ 15 (-25%)
Mutual labels:  sound

AudioFile

Build Status Maven Central

statement

AudioFile is a Scala library to read and write audio files. It is (C)opyright 2004–2021 by Hanns Holger Rutz. All rights reserved. AudioFile is released under the GNU Affero General Public License v3+ and comes with absolutely no warranties. To contact the author, send an e-mail to contact at sciss.de.

requirements / installation

AudioFile builds with sbt against Scala 2.13, 2.12, Dotty (JVM) and Scala 2.13 (JS). The last version to support Scala 2.11 was v1.5.3.

To use the library in your project:

"de.sciss" %% "audiofile" % v

The current version v is "2.4.0"

contributing

Please see the file CONTRIBUTING.md

supported formats

name read/write notes
AIFF R/W
WAVE R/W
IRCAM R/W aka BICSF
NeXT R/W aka Snd and AU
Wave64 R/W
Raw R/W headerless

getting started

AudioFile currently supports reading and writing files in compressed (professional) audio formats such as AIFF, Wave or Wave64. It focuses on the audio data, while currently not supporting meta-data features such as markers, regions, or application specific data stored in the file headers.

The original API was made for synchronous I/O on the JVM:

  • To open an audio file for reading: AudioFile.openRead(aFile) or AudioFile.openRead(anInputStream). The InputStream variant has limited functionality, e.g. you cannot seek into the file, but only read sequentially. The stream variant can be used to decode files from an HTTP connection or in-memory (ByteArrayInputStream).
  • To just retrieve the specification of an existing file, to see if it can be decoded, what is length, number of channels and format are: AudioFile.readSpec(fileOrPathName).
  • To open a file for writing: AudioFile.openWrite(aFile, spec) or AudioFile.openWrite(anOutputStream, spec)

More recently, an asynchronous I/O API was added, which is the only API available on Scala.js, as the JavaScript virtual machine does not allow synchronous I/O. On the JVM, synchronous I/O is slightly faster and allows for a much simpler control flow (no need to map futures).

To the user, frame data is always represented as de-interleaved 64-bit floating point data, so you create a user buffer through Array.ofDim[Double](numChannels, bufFrames), or use a convenience method such as AudioFile.buffer(...). In other words, all sample frames are mapped from their native SampleFormat such as 16-bit integer to floating-point numbers in the range -1 to +1. Integers up to 32-bit can be represented this way without loss of precision. In the future, we might support the native storage format and/or 32-bit floating point data (like it used to be before version 2.3.0).

The synchronous AudioFile implementation is currently not thread-safe, so one should use a single file only from within the same thread. Alternatively, use a lock and validate the frame position before each read/write. The asynchronous API should be fairly thread-safe on the JVM; currently it is not permitted to run more than a single read or write operation at a time.

Here is an example of opening an existing file with synchronous I/O, reading through it to determine the maximum sample magnitude, then writing a normalized version to a new file:

    
import de.sciss.audiofile._

val in      = AudioFile.openRead("input.aif")
// for the output, switch to AIFF 24-bit integer, 
// but keep the other parameters (sample-rate and number-of-channels)
val outSpec = in.spec.copy(fileType = AudioFileType.AIFF, 
                           sampleFormat = SampleFormat.Int24)
val out     = AudioFile.openWrite("output.aif", outSpec)

// create a buffer
val bufSz   = 8192  // perform operations in blocks of this size
val buf     = in.buffer(bufSz)

// first pass: determine maximum magnitude
var mag     = 0.0
var remain  = in.numFrames
while (remain > 0) {
  val chunk = math.min(bufSz, remain).toInt
  in.read(buf, 0, chunk)
  buf.foreach { chan =>
    mag = math.max(mag, math.abs(chan.maxBy(math.abs)))
  }
  remain -= chunk
}
println(f"Maximum magnitude detected: $mag%1.3f")

// second pass: adjust gain and write output
require(mag > 0)
val gain = 1.0 / mag
in.seek(0L) // start over from the beginning of the file
remain = in.numFrames
while (remain > 0) {
  val chunk = math.min(bufSz, remain).toInt
  in.read(buf, 0, chunk)
  buf.foreach { chan =>
    for (i <- 0 until chunk) {
      chan(i) *= gain
    }
  }
  out.write(buf, 0, chunk)
  remain -= chunk
}
out.close()
in.close()

Scala.js

Scala.js does not know the type java.io.File and does not support synchronous I/O. The asynchronous I/O API uses abstractions AsyncReadableByteChannel and AsyncWriteableByteChannel which are modelled after NIO's asynchronous byte and file channels. Files are opened with openReadAsync and openWriteAsync, using a URI. We currently implement a virtual file system with schema idb for IndexedDB, i.e. for accessing and storing files in a website's client side browser cache.

properties

There is a system property AudioFile.DirectMemory whose value can be set to true in order to use direct-memory buffers (ByteBuffer.allocateDirect). Reading in a 1.6 GB is around 18% faster with direct memory. Direct memory can have the disadvantage that it requires an individual VM switch to adjust the maximum available memory before throwing an out-of-memory error. The default is false.

Using an asynchronous file I/O is around 26% slower than synchronous I/O (on JVM).

For all further information, please refer to the API docs. They can be created with sbt doc.

change log

  • v2.2.0: adds Scala.js support and asynchronous API. The base package was renamed from de.sciss.synth.io to de.sciss.audiofile.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].