Class: WaveFile::Format

Inherits:
Object
  • Object
show all
Defined in:
lib/wavefile/format.rb

Overview

Public: Represents information about the data format for a Wave file, such as number of channels, bits per sample, sample rate, and so forth. A Format instance is used by Reader to indicate what format to read samples out as, and by Writer to indicate what format to write samples as.

Direct Known Subclasses

UnvalidatedFormat

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(channels, format_code, sample_rate, speaker_mapping: nil) ⇒ Format

Public: Constructs a new immutable Format.

channels - The number of channels in the format. Can either be an Integer

(e.g. 1, 2, 3) or the symbols +:mono+ (equivalent to 1) or
+:stereo+ (equivalent to 2).

format_code - A symbol indicating the format of each sample. Consists of

two parts: a format code, and the bits per sample. The valid
values are +:pcm_8+, +:pcm_16+, +:pcm_24+, +:pcm_32+, +:float_32+,
+:float_64+, and +:float+ (equivalent to +:float_32+)

sample_rate - The number of samples per second, such as 44100 speaker_mapping - An optional array which indicates which speaker each channel should be

mapped to. Each value in the array should be one of these values:

+:front_left+, +:front_right+, +:front_center+, +:low_frequency+, +:back_left+,
+:back_right+, +:front_left_of_center+, +:front_right_of_center+,
+:back_center+, +:side_left+, +:side_right+, +:top_center+, +:top_front_left+,
+:top_front_center+, +:top_front_right+, +:top_back_left+, +:top_back_center+,
+:top_back_right+.

Each value should only appear once, and the channels must follow the ordering above.

For example, <code>[:front_center, :back_left]</code>
is a valid speaker mapping, but <code>[:back_left, :front_center]</code> is not.
If a given channel should not be mapped to a specific speaker, the
value +:undefined+ can be used. If this field is omitted, a default
value for the given number of channels. For example, if there are 2
channels, this will be set to <code>[:front_left, :front_right]</code>.

Examples

format = Format.new(1, :pcm_16, 44100)
format = Format.new(:mono, :pcm_16, 44100)  # Equivalent to above

format = Format.new(:stereo, :float_32, 44100)
format = Format.new(:stereo, :float, 44100)  # Equivalent to above

format = Format.new(2, :pcm_16, 44100, speaker_mapping: [:front_right, :front_center])

# Channels should explicitly not be mapped to particular speakers
# (otherwise, if no speaker_mapping set, it will be set to a default
# value for the number of channels).
format = Format.new(2, :pcm_16, 44100, speaker_mapping: [:undefined, :undefined])

# Will result in InvalidFormatError, because speakers are defined in
# invalid order
format = Format.new(2, :pcm_16, 44100, speaker_mapping: [:front_right, :front_left])

# speaker_mapping will be set to [:front_left, :undefined, :undefined],
# because channels without a speaker mapping will be mapped to :undefined
format = Format.new(3, :pcm_16, 44100, speaker_mapping: [:front_left])

Raises InvalidFormatError if the given arguments are invalid.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/wavefile/format.rb', line 74

def initialize(channels, format_code, sample_rate, speaker_mapping: nil)
  channels = normalize_channels(channels)

  validate_channels(channels)
  validate_format_code(format_code)
  validate_sample_rate(sample_rate)

  sample_format, bits_per_sample = normalize_format_code(format_code)

  speaker_mapping = normalize_speaker_mapping(channels, speaker_mapping)
  validate_speaker_mapping(channels, speaker_mapping)

  @channels = channels
  @sample_format = sample_format
  @bits_per_sample = bits_per_sample
  @sample_rate = sample_rate
  @block_align = (@bits_per_sample / 8) * @channels
  @byte_rate = @block_align * @sample_rate
  @speaker_mapping = speaker_mapping
end

Instance Attribute Details

#bits_per_sampleObject (readonly)

Public: Returns the number of bits per sample, such as 8, 16, 24, 32, or 64.



114
115
116
# File 'lib/wavefile/format.rb', line 114

def bits_per_sample
  @bits_per_sample
end

#block_alignObject (readonly)

Public: Returns the number of bytes in each sample frame. For example, in a 16-bit stereo file, this will be 4 (2 bytes for each 16-bit sample, times 2 channels).



121
122
123
# File 'lib/wavefile/format.rb', line 121

def block_align
  @block_align
end

#byte_rateObject (readonly)

Public: Returns the number of bytes contained in 1 second of sample data. Is equivalent to #block_align * #sample_rate.



125
126
127
# File 'lib/wavefile/format.rb', line 125

def byte_rate
  @byte_rate
end

#channelsObject (readonly)

Public: Returns the number of channels, such as 1 or 2. This will always return a Integer, even if the number of channels is specified with a symbol (e.g. :mono) in the constructor.



108
109
110
# File 'lib/wavefile/format.rb', line 108

def channels
  @channels
end

#sample_formatObject (readonly)

Public: Returns a symbol indicating the sample format, such as :pcm or :float



111
112
113
# File 'lib/wavefile/format.rb', line 111

def sample_format
  @sample_format
end

#sample_rateObject (readonly)

Public: Returns the number of samples per second, such as 44100.



117
118
119
# File 'lib/wavefile/format.rb', line 117

def sample_rate
  @sample_rate
end

#speaker_mappingObject (readonly)

Public: Returns the mapping of each channel to a speaker.



128
129
130
# File 'lib/wavefile/format.rb', line 128

def speaker_mapping
  @speaker_mapping
end

Instance Method Details

#mono?Boolean

Public: Returns true if the format has 1 channel, false otherwise.

Returns:

  • (Boolean)


96
97
98
# File 'lib/wavefile/format.rb', line 96

def mono?
  @channels == 1
end

#stereo?Boolean

Public: Returns true if the format has 2 channels, false otherwise.

Returns:

  • (Boolean)


101
102
103
# File 'lib/wavefile/format.rb', line 101

def stereo?
  @channels == 2
end