2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
23 ==============================================================================
32 //==============================================================================
34 Reads samples from an audio file stream.
36 A subclass that reads a specific type of audio format will be created by
37 an AudioFormat object.
39 @see AudioFormat, AudioFormatWriter
43 class JUCE_API AudioFormatReader
46 //==============================================================================
47 /** Creates an AudioFormatReader object.
49 @param sourceStream the stream to read from - this will be deleted
50 by this object when it is no longer needed. (Some
51 specialised readers might not use this parameter and
52 can leave it as nullptr).
53 @param formatName the description that will be returned by the getFormatName()
56 AudioFormatReader (InputStream
* sourceStream
,
57 const String
& formatName
);
61 virtual ~AudioFormatReader();
63 //==============================================================================
64 /** Returns a description of what type of format this is.
68 const String
& getFormatName() const noexcept
{ return formatName
; }
70 //==============================================================================
71 /** Reads samples from the stream.
73 @param destChannels an array of float buffers into which the sample data for each
74 channel will be written. Channels that aren't needed can be null
75 @param numDestChannels the number of array elements in the destChannels array
76 @param startSampleInSource the position in the audio file or stream at which the samples
77 should be read, as a number of samples from the start of the
78 stream. It's ok for this to be beyond the start or end of the
79 available data - any samples that are out-of-range will be returned
81 @param numSamplesToRead the number of samples to read. If this is greater than the number
82 of samples that the file or stream contains. the result will be padded
84 @returns true if the operation succeeded, false if there was an error. Note
85 that reading sections of data beyond the extent of the stream isn't an
86 error - the reader should just return zeros for these regions
89 bool read (float* const* destChannels
, int numDestChannels
,
90 int64 startSampleInSource
, int numSamplesToRead
);
92 /** Reads samples from the stream.
94 @param destChannels an array of buffers into which the sample data for each
95 channel will be written.
96 If the format is fixed-point, each channel will be written
97 as an array of 32-bit signed integers using the full
98 range -0x80000000 to 0x7fffffff, regardless of the source's
99 bit-depth. If it is a floating-point format, you should cast
100 the resulting array to a (float**) to get the values (in the
101 range -1.0 to 1.0 or beyond)
102 If the format is stereo, then destChannels[0] is the left channel
103 data, and destChannels[1] is the right channel.
104 The numDestChannels parameter indicates how many pointers this array
105 contains, but some of these pointers can be null if you don't want to
106 read data for some of the channels
107 @param numDestChannels the number of array elements in the destChannels array
108 @param startSampleInSource the position in the audio file or stream at which the samples
109 should be read, as a number of samples from the start of the
110 stream. It's ok for this to be beyond the start or end of the
111 available data - any samples that are out-of-range will be returned
113 @param numSamplesToRead the number of samples to read. If this is greater than the number
114 of samples that the file or stream contains. the result will be padded
116 @param fillLeftoverChannelsWithCopies if true, this indicates that if there's no source data available
117 for some of the channels that you pass in, then they should be filled with
118 copies of valid source channels.
119 E.g. if you're reading a mono file and you pass 2 channels to this method, then
120 if fillLeftoverChannelsWithCopies is true, both destination channels will be filled
121 with the same data from the file's single channel. If fillLeftoverChannelsWithCopies
122 was false, then only the first channel would be filled with the file's contents, and
123 the second would be cleared. If there are many channels, e.g. you try to read 4 channels
124 from a stereo file, then the last 3 would all end up with copies of the same data.
125 @returns true if the operation succeeded, false if there was an error. Note
126 that reading sections of data beyond the extent of the stream isn't an
127 error - the reader should just return zeros for these regions
130 bool read (int* const* destChannels
,
132 int64 startSampleInSource
,
133 int numSamplesToRead
,
134 bool fillLeftoverChannelsWithCopies
);
136 /** Fills a section of an AudioBuffer from this reader.
138 This will convert the reader's fixed- or floating-point data to
139 the buffer's floating-point format, and will try to intelligently
140 cope with mismatches between the number of channels in the reader
143 @returns true if the operation succeeded, false if there was an error. Note
144 that reading sections of data beyond the extent of the stream isn't an
145 error - the reader should just return zeros for these regions
147 bool read (AudioBuffer
<float>* buffer
,
148 int startSampleInDestBuffer
,
150 int64 readerStartSample
,
151 bool useReaderLeftChan
,
152 bool useReaderRightChan
);
154 /** Finds the highest and lowest sample levels from a section of the audio stream.
156 This will read a block of samples from the stream, and measure the
157 highest and lowest sample levels from the channels in that section, returning
158 these as normalised floating-point levels.
160 @param startSample the offset into the audio stream to start reading from. It's
161 ok for this to be beyond the start or end of the stream.
162 @param numSamples how many samples to read
163 @param results this array will be filled with Range values for each channel.
164 The array must contain numChannels elements.
165 @param numChannelsToRead the number of channels of data to scan. This must be
166 more than zero, but not more than the total number of channels
167 that the reader contains
170 virtual void readMaxLevels (int64 startSample
, int64 numSamples
,
171 Range
<float>* results
, int numChannelsToRead
);
173 /** Finds the highest and lowest sample levels from a section of the audio stream.
175 This will read a block of samples from the stream, and measure the
176 highest and lowest sample levels from the channels in that section, returning
177 these as normalised floating-point levels.
179 @param startSample the offset into the audio stream to start reading from. It's
180 ok for this to be beyond the start or end of the stream.
181 @param numSamples how many samples to read
182 @param lowestLeft on return, this is the lowest absolute sample from the left channel
183 @param highestLeft on return, this is the highest absolute sample from the left channel
184 @param lowestRight on return, this is the lowest absolute sample from the right
185 channel (if there is one)
186 @param highestRight on return, this is the highest absolute sample from the right
187 channel (if there is one)
190 virtual void readMaxLevels (int64 startSample
, int64 numSamples
,
191 float& lowestLeft
, float& highestLeft
,
192 float& lowestRight
, float& highestRight
);
194 /** Scans the source looking for a sample whose magnitude is in a specified range.
196 This will read from the source, either forwards or backwards between two sample
197 positions, until it finds a sample whose magnitude lies between two specified levels.
199 If it finds a suitable sample, it returns its position; if not, it will return -1.
201 There's also a minimumConsecutiveSamples setting to help avoid spikes or zero-crossing
202 points when you're searching for a continuous range of samples
204 @param startSample the first sample to look at
205 @param numSamplesToSearch the number of samples to scan. If this value is negative,
206 the search will go backwards
207 @param magnitudeRangeMinimum the lowest magnitude (inclusive) that is considered a hit, from 0 to 1.0
208 @param magnitudeRangeMaximum the highest magnitude (inclusive) that is considered a hit, from 0 to 1.0
209 @param minimumConsecutiveSamples if this is > 0, the method will only look for a sequence
210 of this many consecutive samples, all of which lie
211 within the target range. When it finds such a sequence,
212 it returns the position of the first in-range sample
213 it found (i.e. the earliest one if scanning forwards, the
214 latest one if scanning backwards)
216 int64
searchForLevel (int64 startSample
,
217 int64 numSamplesToSearch
,
218 double magnitudeRangeMinimum
,
219 double magnitudeRangeMaximum
,
220 int minimumConsecutiveSamples
);
223 //==============================================================================
224 /** The sample-rate of the stream. */
225 double sampleRate
= 0;
227 /** The number of bits per sample, e.g. 16, 24, 32. */
228 unsigned int bitsPerSample
= 0;
230 /** The total number of samples in the audio stream. */
231 int64 lengthInSamples
= 0;
233 /** The total number of channels in the audio stream. */
234 unsigned int numChannels
= 0;
236 /** Indicates whether the data is floating-point or fixed. */
237 bool usesFloatingPointData
= false;
239 /** A set of metadata values that the reader has pulled out of the stream.
241 Exactly what these values are depends on the format, so you can
242 check out the format implementation code to see what kind of stuff
245 StringPairArray metadataValues
;
247 /** The input stream, for use by subclasses. */
250 //==============================================================================
251 /** Get the channel layout of the audio stream. */
252 virtual AudioChannelSet
getChannelLayout();
254 //==============================================================================
255 /** Subclasses must implement this method to perform the low-level read operation.
257 Callers should use read() instead of calling this directly.
259 @param destChannels the array of destination buffers to fill. Some of these
261 @param numDestChannels the number of items in the destChannels array. This
262 value is guaranteed not to be greater than the number of
263 channels that this reader object contains
264 @param startOffsetInDestBuffer the number of samples from the start of the
265 dest data at which to begin writing
266 @param startSampleInFile the number of samples into the source data at which
267 to begin reading. This value is guaranteed to be >= 0.
268 @param numSamples the number of samples to read
270 virtual bool readSamples (int** destChannels
,
272 int startOffsetInDestBuffer
,
273 int64 startSampleInFile
,
278 //==============================================================================
279 /** Used by AudioFormatReader subclasses to copy data to different formats. */
280 template <class DestSampleType
, class SourceSampleType
, class SourceEndianness
>
283 using DestType
= AudioData::Pointer
<DestSampleType
, AudioData::NativeEndian
, AudioData::NonInterleaved
, AudioData::NonConst
>;
284 using SourceType
= AudioData::Pointer
<SourceSampleType
, SourceEndianness
, AudioData::Interleaved
, AudioData::Const
>;
286 template <typename TargetType
>
287 static void read (TargetType
* const* destData
, int destOffset
, int numDestChannels
,
288 const void* sourceData
, int numSourceChannels
, int numSamples
) noexcept
290 for (int i
= 0; i
< numDestChannels
; ++i
)
292 if (void* targetChan
= destData
[i
])
294 DestType
dest (targetChan
);
297 if (i
< numSourceChannels
)
298 dest
.convertSamples (SourceType (addBytesToPointer (sourceData
, i
* SourceType::getBytesPerSample()), numSourceChannels
), numSamples
);
300 dest
.clearSamples (numSamples
);
306 /** Used by AudioFormatReader subclasses to clear any parts of the data blocks that lie
307 beyond the end of their available length.
309 static void clearSamplesBeyondAvailableLength (int** destChannels
, int numDestChannels
,
310 int startOffsetInDestBuffer
, int64 startSampleInFile
,
311 int& numSamples
, int64 fileLengthInSamples
)
313 if (destChannels
== nullptr)
319 const int64 samplesAvailable
= fileLengthInSamples
- startSampleInFile
;
321 if (samplesAvailable
< numSamples
)
323 for (int i
= numDestChannels
; --i
>= 0;)
324 if (destChannels
[i
] != nullptr)
325 zeromem (destChannels
[i
] + startOffsetInDestBuffer
, (size_t) numSamples
* sizeof (int));
327 numSamples
= (int) samplesAvailable
;
334 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatReader
)