Home

Awesome

libsndfile

GitHub release (latest by date including pre-releases) GitHub (Pre-)Release Date GitHub last commit GitHub

libsndfile provides Scala Native bindings for the Libsndfile C library for sampled sound manipulation.

Overview

The goal of this project is to provide an easy-to-use Scala Native facade for the entire libsndfile C library for sampled sound manipulation. Currently, all the functions and constants needed to write integer sampled sound to all the formats supported by the library are supported. Development is active, and support for the remaining functionality of the library will be added in upcoming releases.

The more "programmer friendly" part of this library is found in the io.github.edadma.libsndfile.facade package. That's the only package you need to import from, as seen in the example below. The other package in the library is io.github.edadma.libsndfile.extern which provides for interaction with the libsndfile C library using Scala Native interoperability elements from the so-call unsafe namespace. There are no public declarations in the io.github.edadma.libsndfile.facade package that use unsafe types in their parameter or return types, making it a pure Scala facade. Consequently, you never have to worry about memory allocation or type conversions.

Usage

To use this library, libsndfile1-dev needs to be installed:

sudo apt install libsndfile1-dev

Include the following in your project/plugins.sbt:

addSbtPlugin("com.codecommit" % "sbt-github-packages" % "0.5.2")

Include the following in your build.sbt:

resolvers += Resolver.githubPackages("edadma")

libraryDependencies += "io.github.edadma" %%% "libsndfile" % "0.1.2"

Use the following import in your code:

import io.github.edadma.libsndfile.facade._

Example

This example is a direct translation of the make_sine example in the C library repository. It generates a WAV uncompressed audio file called "sine.wav", which plays a 4-second sound at 344Hz in the left channel and 466Hz in the right channel.

import math._

import io.github.edadma.libsndfile.facade._

object Main extends App {

  val SAMPLE_RATE  = 44100
  val SAMPLE_COUNT = SAMPLE_RATE * 4 /* 4 seconds */
  val AMPLITUDE    = 1.0 * 0x7F000000
  val LEFT_FREQ    = 344.0 / SAMPLE_RATE
  val RIGHT_FREQ   = 466.0 / SAMPLE_RATE

  val (sndfile, sfinfo) = sf_open("sine.wav",
                                  SFM_WRITE,
                                  SFInfo(samplerate = SAMPLE_RATE,
                                         frames = SAMPLE_COUNT,
                                         channels = 2,
                                         format = SF_FORMAT_WAV subtype SF_FORMAT_PCM_24))

  if (sfinfo.channels > 2) {
    println("Error : can only generate mono or stereo files.")
    sndfile.close
    sys.exit(1)
  }

  def sample(k: Int): Int =
    if (sfinfo.channels == 1) (AMPLITUDE * sin(LEFT_FREQ * 2 * k * Pi)).toInt
    else { // stereo
      if ((k & 1) == 0) // left channel indexes are even
        (AMPLITUDE * sin(LEFT_FREQ * k * Pi)).toInt // k = 2*i where i is the right channel sample
      else (AMPLITUDE * sin(RIGHT_FREQ * (k - 1) * Pi)).toInt // k = 2*i + 1 where i is the left channel sample
    }

  if (sndfile.write_int(sample, sfinfo.channels * SAMPLE_COUNT) != sfinfo.channels * SAMPLE_COUNT)
    println(sndfile.strerror)

  sndfile.close

}

Documentation

API documentation is forthcoming, however documentation for the C library is found here.

License

ISC