LAME
FFI powered library for the LAME MP3 encoder.
Installation
Add this line to your application's Gemfile:
gem 'lame'
And then execute:
$ bundle
Or install it yourself as:
$ gem install lame
Usage
Create a default LAME::Encoder
with default settings:
encoder = LAME::Encoder.new
Then configure some settings:
encoder.configure do |config|
config.quality = 4
config.bitrate = 192
end
See all configuration options in the Configuration section below.
Then encode some audio data. Both left
and right
are arrays of short
values (ranging from −32,768 to +32,767). The mp3_data
variable is a
binary string of MP3 encoded audio. This can be appended to a file or
streamed to a server.
encoder.encode_short(left, right) do |mp3_data|
# do something with encoded mp3 data..
end
See all encoding methods in the Encoding section below.
Configuration
(work in progress)
# These are the defaults:
encoder.configure do |config|
config.number_of_samples = 4294967295
config.input_samplerate = 44100
config.number_of_channels = 2
config.scale = 0.95
config.scale_left = 1.0
config.scale_left = 1.0
config.output_samplerate = 44100
config.analysis = false
config.decode_only = false
config.quality = 3
config.mode = :join_stereo
config.force_mid_side = false
config.free_format = false
config.replay_gain = false
config.decode_on_the_fly = false
config.bitrate = 128
config.preset = :EXTREME # no LAME default
config.copyright = false
config.original = true
config.error_protection = false
config.extension = false
config.strict_iso = true # no LAME default
config.allow_different_block_types = false
config.temporal_masking = true
config.inter_channel_ratio = 0.0002
config.disable_short_blocks = false
config.force_short_blocks = false
config.emphasis = false
# auto-detected by default
config.asm_optimization.mmx = true
config.asm_optimization.amd3now = true
config.asm_optimization.sse = true
# these values can't be "unset" once set to true
config.id3.v2 = false
config.id3.v1_only = false
config.id3.v2_only = false
config.id3.v1_space = false
config.id3.v2_padding = false
config.id3.v2_padding_size = 128
config.quantization.reservoir = true
config.quantization.comp = 9
config.quantization.comp_short = 9
config.quantization.experimental_x = 9
config.quantization.experimental_y = 0
config.quantization.experimental_z = 0
config.quantization.naoki = true
config.quantization.msfix = 1.95
config.vbr.write_tag = true
config.vbr.mode = :vbr_off
config.vbr.q = 4
config.vbr.quality = 4.0
config.vbr.mean_bitrate = 128
config.vbr.min_bitrate = 0
config.vbr.max_bitrate = 0
config.vbr.enforce_min_bitrate = false
config.filtering.low_pass_frequency = 17000
config.filtering.low_pass_width = -1
config.filtering.high_pass_frequency = 0
config.filtering.high_pass_width = -1
config.psycho_acoustics.ath_only = false
config.psycho_acoustics.ath_short = false
config.psycho_acoustics.ath = true
config.psycho_acoustics.ath_type = 4
config.psycho_acoustics.ath_lower = 3.0
config.psycho_acoustics.athaa_type = -1
config.psycho_acoustics.athaa_sensitivity = 0.0
end
Encoding
See spec/integration/encoding_spec.rb
for an example how to encode a WAV file
to an MP3 file.
The available encoding functions are:
encoder = LAME::Encoder.new
# encode shorts (−32,768 to +32,767), for 16-bit audio
encoder.encode_short(left, right) do |mp3_frame|
# ...
end
# encode floats (−1.0 to +1.0), for 32-bit floating point audio
encoder.encode_float(left, right) do |mp3_frame|
# ...
end
# encode longs (system dependent, +/- 2^(bits_per_long-1)
encoder.encode_long(left, right) do |mp3_frame|
# ...
end
# encode interleaved shorts
encoder.encode_interleaved_short(samples) do |mp3_frame|
# ...
end
# encode interleaved floats
encoder.encode_interleaved_float(samples) do |mp3_frame|
# ...
end
The left
and right
are arrays of sample values for the given data type.
Decoding
See spec/integration/decoding_spec.rb
for an example how to decode an MP3 file
to an WAV file.
Development
This section contains some references used during development of this gem.
ID3v2 tags
To use ID3v2 tags in files, see this post on the lame-dev
mailing list:
http://sourceforge.net/mailarchive/message.php?msg_id=18557283
So:
- Disable automatic id3tag writing
- Write id3v2 tag at start of file (keep track of size of this tag)
- Write audio to file
- Write id3v1 tag at end of file
- Write vbr 'lametag' at start of audio (using the size of the id3v2 tag)
See the example code in spec/integration/encoding_spec.rb
for an example.
Decoding
Check this link for a 'simple' example. Note that we need to deal with the ID3 tags ourselves before decoding MP3 frames.
http://sourceforge.net/mailarchive/message.php?msg_id=26907120
Analysis of lame_decode_initfile
in get_audio.c
:
hip_decode_init
- Read ID3 tags, starting with "ID3"
- The length of the ID3 tag are at the start (right after "ID3")
- Optionally read the contents of the ID3 tag, or just skip it
- Check if there is a "AID" header, and skip it
- Read up until the first "mp123 syncword"
After this, we are ready to decode MP3 data.
- Check if there are some samples in the internal decoder by passing an empty input-buffer into the decoder.
- If some decoded audio samples were indeed left in the internal decoder, do something useful with them.
- Repeat this until no audio is left in the internal buffer.
- Read some data from the file (starting at the "mp123 syncword") and feed it to the decoder.
- Handle the decoded audio.
- Now repeat this process (
GOTO 1
) until the end of the MP3 file.
See the example code in spec/integration/decoding_spec.rb
for an example.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request