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, [:front_center, :back_left]
is a valid speaker mapping, but [:back_left, :front_center] 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 [:front_left, :front_right].

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.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/wavefile/format.rb', line 70

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.



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

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).



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

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.



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

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.



104
105
106
# File 'lib/wavefile/format.rb', line 104

def channels
  @channels
end

#sample_formatObject (readonly)

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



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

def sample_format
  @sample_format
end

#sample_rateObject (readonly)

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



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

def sample_rate
  @sample_rate
end

#speaker_mappingObject (readonly)

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



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

def speaker_mapping
  @speaker_mapping
end

Instance Method Details

#mono?Boolean

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

Returns:

  • (Boolean)


92
93
94
# File 'lib/wavefile/format.rb', line 92

def mono?
  @channels == 1
end

#stereo?Boolean

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

Returns:

  • (Boolean)


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

def stereo?
  @channels == 2
end