/shine-mp3

Pure Go port of Shine MP3 Encoder

Primary LanguageGoOtherNOASSERTION

shine-mp3

This is a pure Go implementation of the shine mp3 encoding library.

shine is a blazing fast mp3 encoding library implemented in fixed-point arithmetic. The library can thus be used to perform super fast mp3 encoding on architectures without a FPU, such as armel, etc.. It is also super fast on architectures with a FPU!

AFAIK, this is the only pure Go MP3 encoding library. This project currently produces byte-identical binaries to the original Shine C library.

The industry leading LAME MP3 encoding library says this about Shine:

Shine is a featureless, but clean and readable MP3 encoder by Gabriel Bouvigne of LAME fame. Great as a starting point or learning tool. Also probably the only open source, fixed point math MP3 encoder.

This means shine-mp3 will produce compressed files that are valid MP3 files and sound good, but they will:

  • be larger than MP3 files produced by better libraries (i.e. LAME)
  • be of less quality than MP3 files produced by better libraries (i.e. LAME)
  • contain no ID3 metadata

Usage

The main.go file has simple example of reading WAV file and encoding it to MP3. It all comes down to this:

// Create the encoder with the sample rate and number of audio channels
mp3Encoder := NewEncoder(44100, 2)
// Assuming all your audio data is in []int16 slice called decodedData, write it to a file referenced by out
mp3Encoder.Write(out, decodedData)

A Quick Comment on MP3 Encoders

There is essentially one actively maintained MP3 encoding library: LAME MP3. If you want to encode audio files to MP3 using a programming language, you use a library that provides bindings to LAME, which means users of your software must have the LAME MP3 C library installed. You might be able to work around this by producing a 100% statically compiled binary and including the LAME files inside. However, that can prove challenging on all platforms, especially Windows.

I found about the Shine MP3 encoder from this list of alternative encoders on the LAME website.

Development

The Dockerfile is provided. It builds and install both the original C library and shine-mp3:

# Create the container
docker build -t shine .
# Convert a WAV file with Go implementation
docker run -it --rm -v $(pwd):$(pwd) -w $(pwd) shine-encoder shine-mp3 testdata/test.wav test.Go.mp3
# Convert it with the original C implementation
docker run -it --rm -v $(pwd):$(pwd) -w $(pwd) shine-encoder shineenc testdata/test.wav test.C.mp3
# Confirm the same files were created
md5sum *.mp3
c255da6921a5a726547ce6a323dfe95e  test.C.mp3
c255da6921a5a726547ce6a323dfe95e  test.Go.mp3

MP3 Encoder Algorithm

I spent quite a lot of time researching MP3 and here's what I found:

  • There is no encoder specification
    • The Library of Congress is a good place to start. It references ISO docs 13818-3 and 11172-3 but they are behind paywalls, so essentially a dead-end for hobbyist like me.
    • From Wikipedia,

      The MPEG-1 standard does not include a precise specification for an MP3 encoder but does provide examples of psychoacoustic models, rate loops, and the like in the non-normative part of the original standard...When this was written, the suggested implementations were quite dated. Implementers of the standard were supposed to devise algorithms suitable for removing parts of the information from the audio input. As a result, many different MP3 encoders became available, each producing files of differing quality

  • MP3 was licensed until 2017, stifling access, interest, and innovation

I archived documents that helped: