Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/javax/sound/sampled/AudioFormat.java
41159 views
1
/*
2
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.sound.sampled;
27
28
import java.util.Collections;
29
import java.util.HashMap;
30
import java.util.Map;
31
import java.util.Objects;
32
33
/**
34
* {@code AudioFormat} is the class that specifies a particular arrangement of
35
* data in a sound stream. By examining the information stored in the audio
36
* format, you can discover how to interpret the bits in the binary sound data.
37
* <p>
38
* Every data line has an audio format associated with its data stream. The
39
* audio format of a source (playback) data line indicates what kind of data the
40
* data line expects to receive for output. For a target (capture) data line,
41
* the audio format specifies the kind of the data that can be read from the
42
* line.
43
* <p>
44
* Sound files also have audio formats, of course. The {@link AudioFileFormat}
45
* class encapsulates an {@code AudioFormat} in addition to other, file-specific
46
* information. Similarly, an {@link AudioInputStream} has an
47
* {@code AudioFormat}.
48
* <p>
49
* The {@code AudioFormat} class accommodates a number of common sound-file
50
* encoding techniques, including pulse-code modulation (PCM), mu-law encoding,
51
* and a-law encoding. These encoding techniques are predefined, but service
52
* providers can create new encoding types. The encoding that a specific format
53
* uses is named by its {@code encoding} field.
54
* <p>
55
* In addition to the encoding, the audio format includes other properties that
56
* further specify the exact arrangement of the data. These include the number
57
* of channels, sample rate, sample size, byte order, frame rate, and frame
58
* size. Sounds may have different numbers of audio channels: one for mono, two
59
* for stereo. The sample rate measures how many "snapshots" (samples) of the
60
* sound pressure are taken per second, per channel. (If the sound is stereo
61
* rather than mono, two samples are actually measured at each instant of time:
62
* one for the left channel, and another for the right channel; however, the
63
* sample rate still measures the number per channel, so the rate is the same
64
* regardless of the number of channels. This is the standard use of the term.)
65
* The sample size indicates how many bits are used to store each snapshot; 8
66
* and 16 are typical values. For 16-bit samples (or any other sample size
67
* larger than a byte), byte order is important; the bytes in each sample are
68
* arranged in either the "little-endian" or "big-endian" style. For encodings
69
* like PCM, a frame consists of the set of samples for all channels at a given
70
* point in time, and so the size of a frame (in bytes) is always equal to the
71
* size of a sample (in bytes) times the number of channels. However, with some
72
* other sorts of encodings a frame can contain a bundle of compressed data for
73
* a whole series of samples, as well as additional, non-sample data. For such
74
* encodings, the sample rate and sample size refer to the data after it is
75
* decoded into PCM, and so they are completely different from the frame rate
76
* and frame size.
77
* <p>
78
* An {@code AudioFormat} object can include a set of properties. A property is
79
* a pair of key and value: the key is of type {@code String}, the associated
80
* property value is an arbitrary object. Properties specify additional format
81
* specifications, like the bit rate for compressed formats. Properties are
82
* mainly used as a means to transport additional information of the audio
83
* format to and from the service providers. Therefore, properties are ignored
84
* in the {@link #matches(AudioFormat)} method. However, methods which rely on
85
* the installed service providers, like
86
* {@link AudioSystem#isConversionSupported (AudioFormat, AudioFormat)
87
* isConversionSupported} may consider properties, depending on the respective
88
* service provider implementation.
89
* <p>
90
* The following table lists some common properties which service providers
91
* should use, if applicable:
92
*
93
* <table class="striped">
94
* <caption>Audio Format Properties</caption>
95
* <thead>
96
* <tr>
97
* <th scope="col">Property key
98
* <th scope="col">Value type
99
* <th scope="col">Description
100
* </thead>
101
* <tbody>
102
* <tr>
103
* <th scope="row">"bitrate"
104
* <td>{@link java.lang.Integer Integer}
105
* <td>average bit rate in bits per second
106
* <tr>
107
* <th scope="row">"vbr"
108
* <td>{@link java.lang.Boolean Boolean}
109
* <td>{@code true}, if the file is encoded in variable bit rate (VBR)
110
* <tr>
111
* <th scope="row">"quality"
112
* <td>{@link java.lang.Integer Integer}
113
* <td>encoding/conversion quality, 1..100
114
* </tbody>
115
* </table>
116
* <p>
117
* Vendors of service providers (plugins) are encouraged to seek information
118
* about other already established properties in third party plugins, and follow
119
* the same conventions.
120
*
121
* @author Kara Kytle
122
* @author Florian Bomers
123
* @see DataLine#getFormat
124
* @see AudioInputStream#getFormat
125
* @see AudioFileFormat
126
* @see javax.sound.sampled.spi.FormatConversionProvider
127
* @since 1.3
128
*/
129
public class AudioFormat {
130
131
/**
132
* The audio encoding technique used by this format.
133
*/
134
protected Encoding encoding;
135
136
/**
137
* The number of samples played or recorded per second, for sounds that have
138
* this format.
139
*/
140
protected float sampleRate;
141
142
/**
143
* The number of bits in each sample of a sound that has this format.
144
*/
145
protected int sampleSizeInBits;
146
147
/**
148
* The number of audio channels in this format (1 for mono, 2 for stereo).
149
*/
150
protected int channels;
151
152
/**
153
* The number of bytes in each frame of a sound that has this format.
154
*/
155
protected int frameSize;
156
157
/**
158
* The number of frames played or recorded per second, for sounds that have
159
* this format.
160
*/
161
protected float frameRate;
162
163
/**
164
* Indicates whether the audio data is stored in big-endian or little-endian
165
* order.
166
*/
167
protected boolean bigEndian;
168
169
/**
170
* The set of properties.
171
*/
172
private HashMap<String, Object> properties;
173
174
/**
175
* Constructs an {@code AudioFormat} with the given parameters. The encoding
176
* specifies the convention used to represent the data. The other parameters
177
* are further explained in the {@link AudioFormat class description}.
178
*
179
* @param encoding the audio encoding technique
180
* @param sampleRate the number of samples per second
181
* @param sampleSizeInBits the number of bits in each sample
182
* @param channels the number of channels (1 for mono, 2 for stereo, and so
183
* on)
184
* @param frameSize the number of bytes in each frame
185
* @param frameRate the number of frames per second
186
* @param bigEndian indicates whether the data for a single sample is
187
* stored in big-endian byte order ({@code false} means
188
* little-endian)
189
*/
190
public AudioFormat(Encoding encoding, float sampleRate, int sampleSizeInBits,
191
int channels, int frameSize, float frameRate, boolean bigEndian) {
192
193
this.encoding = encoding;
194
this.sampleRate = sampleRate;
195
this.sampleSizeInBits = sampleSizeInBits;
196
this.channels = channels;
197
this.frameSize = frameSize;
198
this.frameRate = frameRate;
199
this.bigEndian = bigEndian;
200
this.properties = null;
201
}
202
203
/**
204
* Constructs an {@code AudioFormat} with the given parameters. The encoding
205
* specifies the convention used to represent the data. The other parameters
206
* are further explained in the {@link AudioFormat class description}.
207
*
208
* @param encoding the audio encoding technique
209
* @param sampleRate the number of samples per second
210
* @param sampleSizeInBits the number of bits in each sample
211
* @param channels the number of channels (1 for mono, 2 for stereo, and so
212
* on)
213
* @param frameSize the number of bytes in each frame
214
* @param frameRate the number of frames per second
215
* @param bigEndian indicates whether the data for a single sample is
216
* stored in big-endian byte order ({@code false} means
217
* little-endian)
218
* @param properties a {@code Map<String, Object>} object containing format
219
* properties
220
* @since 1.5
221
*/
222
public AudioFormat(Encoding encoding, float sampleRate,
223
int sampleSizeInBits, int channels,
224
int frameSize, float frameRate,
225
boolean bigEndian, Map<String, Object> properties) {
226
this(encoding, sampleRate, sampleSizeInBits, channels,
227
frameSize, frameRate, bigEndian);
228
this.properties = new HashMap<>(properties);
229
}
230
231
/**
232
* Constructs an {@code AudioFormat} with a linear PCM encoding and the
233
* given parameters. The frame size is set to the number of bytes required
234
* to contain one sample from each channel, and the frame rate is set to the
235
* sample rate.
236
*
237
* @param sampleRate the number of samples per second
238
* @param sampleSizeInBits the number of bits in each sample
239
* @param channels the number of channels (1 for mono, 2 for stereo, and so
240
* on)
241
* @param signed indicates whether the data is signed or unsigned
242
* @param bigEndian indicates whether the data for a single sample is
243
* stored in big-endian byte order ({@code false} means
244
* little-endian)
245
*/
246
public AudioFormat(float sampleRate, int sampleSizeInBits,
247
int channels, boolean signed, boolean bigEndian) {
248
249
this((signed == true ? Encoding.PCM_SIGNED : Encoding.PCM_UNSIGNED),
250
sampleRate,
251
sampleSizeInBits,
252
channels,
253
(channels == AudioSystem.NOT_SPECIFIED || sampleSizeInBits == AudioSystem.NOT_SPECIFIED)?
254
AudioSystem.NOT_SPECIFIED:
255
((sampleSizeInBits + 7) / 8) * channels,
256
sampleRate,
257
bigEndian);
258
}
259
260
/**
261
* Obtains the type of encoding for sounds in this format.
262
*
263
* @return the encoding type
264
* @see Encoding#PCM_SIGNED
265
* @see Encoding#PCM_UNSIGNED
266
* @see Encoding#ULAW
267
* @see Encoding#ALAW
268
*/
269
public Encoding getEncoding() {
270
return encoding;
271
}
272
273
/**
274
* Obtains the sample rate. For compressed formats, the return value is the
275
* sample rate of the uncompressed audio data. When this {@code AudioFormat}
276
* is used for queries (e.g.
277
* {@link AudioSystem#isConversionSupported(AudioFormat, AudioFormat)
278
* AudioSystem.isConversionSupported}) or capabilities (e.g.
279
* {@link DataLine.Info#getFormats DataLine.Info.getFormats}), a sample rate
280
* of {@code AudioSystem.NOT_SPECIFIED} means that any sample rate is
281
* acceptable. {@code AudioSystem.NOT_SPECIFIED} is also returned when the
282
* sample rate is not defined for this audio format.
283
*
284
* @return the number of samples per second, or
285
* {@code AudioSystem.NOT_SPECIFIED}
286
* @see #getFrameRate()
287
* @see AudioSystem#NOT_SPECIFIED
288
*/
289
public float getSampleRate() {
290
return sampleRate;
291
}
292
293
/**
294
* Obtains the size of a sample. For compressed formats, the return value is
295
* the sample size of the uncompressed audio data. When this
296
* {@code AudioFormat} is used for queries (e.g.
297
* {@link AudioSystem#isConversionSupported(AudioFormat,AudioFormat)
298
* AudioSystem.isConversionSupported}) or capabilities (e.g.
299
* {@link DataLine.Info#getFormats DataLine.Info.getFormats}), a sample size
300
* of {@code AudioSystem.NOT_SPECIFIED} means that any sample size is
301
* acceptable. {@code AudioSystem.NOT_SPECIFIED} is also returned when the
302
* sample size is not defined for this audio format.
303
*
304
* @return the number of bits in each sample, or
305
* {@code AudioSystem.NOT_SPECIFIED}
306
* @see #getFrameSize()
307
* @see AudioSystem#NOT_SPECIFIED
308
*/
309
public int getSampleSizeInBits() {
310
return sampleSizeInBits;
311
}
312
313
/**
314
* Obtains the number of channels. When this {@code AudioFormat} is used for
315
* queries (e.g. {@link AudioSystem#isConversionSupported(AudioFormat,
316
* AudioFormat) AudioSystem.isConversionSupported}) or capabilities (e.g.
317
* {@link DataLine.Info#getFormats DataLine.Info.getFormats}), a return
318
* value of {@code AudioSystem.NOT_SPECIFIED} means that any (positive)
319
* number of channels is acceptable.
320
*
321
* @return The number of channels (1 for mono, 2 for stereo, etc.), or
322
* {@code AudioSystem.NOT_SPECIFIED}
323
* @see AudioSystem#NOT_SPECIFIED
324
*/
325
public int getChannels() {
326
return channels;
327
}
328
329
/**
330
* Obtains the frame size in bytes. When this {@code AudioFormat} is used
331
* for queries (e.g. {@link AudioSystem#isConversionSupported(AudioFormat,
332
* AudioFormat) AudioSystem.isConversionSupported}) or capabilities (e.g.
333
* {@link DataLine.Info#getFormats DataLine.Info.getFormats}), a frame size
334
* of {@code AudioSystem.NOT_SPECIFIED} means that any frame size is
335
* acceptable. {@code AudioSystem.NOT_SPECIFIED} is also returned when the
336
* frame size is not defined for this audio format.
337
*
338
* @return the number of bytes per frame, or
339
* {@code AudioSystem.NOT_SPECIFIED}
340
* @see #getSampleSizeInBits()
341
* @see AudioSystem#NOT_SPECIFIED
342
*/
343
public int getFrameSize() {
344
return frameSize;
345
}
346
347
/**
348
* Obtains the frame rate in frames per second. When this
349
* {@code AudioFormat} is used for queries (e.g.
350
* {@link AudioSystem#isConversionSupported(AudioFormat,AudioFormat)
351
* AudioSystem.isConversionSupported}) or capabilities (e.g.
352
* {@link DataLine.Info#getFormats DataLine.Info.getFormats}), a frame rate
353
* of {@code AudioSystem.NOT_SPECIFIED} means that any frame rate is
354
* acceptable. {@code AudioSystem.NOT_SPECIFIED} is also returned when the
355
* frame rate is not defined for this audio format.
356
*
357
* @return the number of frames per second, or
358
* {@code AudioSystem.NOT_SPECIFIED}
359
* @see #getSampleRate()
360
* @see AudioSystem#NOT_SPECIFIED
361
*/
362
public float getFrameRate() {
363
return frameRate;
364
}
365
366
/**
367
* Indicates whether the audio data is stored in big-endian or little-endian
368
* byte order. If the sample size is not more than one byte, the return
369
* value is irrelevant.
370
*
371
* @return {@code true} if the data is stored in big-endian byte order,
372
* {@code false} if little-endian
373
*/
374
public boolean isBigEndian() {
375
return bigEndian;
376
}
377
378
/**
379
* Obtain an unmodifiable map of properties. The concept of properties is
380
* further explained in the {@link AudioFileFormat class description}.
381
*
382
* @return a {@code Map<String, Object>} object containing all properties.
383
* If no properties are recognized, an empty map is returned.
384
* @see #getProperty(String)
385
* @since 1.5
386
*/
387
@SuppressWarnings("unchecked") // Cast of result of clone.
388
public Map<String,Object> properties() {
389
Map<String,Object> ret;
390
if (properties == null) {
391
ret = new HashMap<>(0);
392
} else {
393
ret = (Map<String,Object>) (properties.clone());
394
}
395
return Collections.unmodifiableMap(ret);
396
}
397
398
/**
399
* Obtain the property value specified by the key. The concept of properties
400
* is further explained in the {@link AudioFileFormat class description}.
401
* <p>
402
* If the specified property is not defined for a particular file format,
403
* this method returns {@code null}.
404
*
405
* @param key the key of the desired property
406
* @return the value of the property with the specified key, or {@code null}
407
* if the property does not exist
408
* @see #properties()
409
* @since 1.5
410
*/
411
public Object getProperty(String key) {
412
if (properties == null) {
413
return null;
414
}
415
return properties.get(key);
416
}
417
418
/**
419
* Indicates whether this format matches the one specified. To match, two
420
* formats must have the same encoding, and consistent values of the number
421
* of channels, sample rate, sample size, frame rate, and frame size. The
422
* values of the property are consistent if they are equal or the specified
423
* format has the property value {@code AudioSystem.NOT_SPECIFIED}. The byte
424
* order (big-endian or little-endian) must be the same if the sample size
425
* is greater than one byte.
426
*
427
* @param format format to test for match
428
* @return {@code true} if this format matches the one specified,
429
* {@code false} otherwise
430
*/
431
public boolean matches(AudioFormat format) {
432
if (format.getEncoding().equals(getEncoding())
433
&& (format.getChannels() == AudioSystem.NOT_SPECIFIED
434
|| format.getChannels() == getChannels())
435
&& (format.getSampleRate() == (float)AudioSystem.NOT_SPECIFIED
436
|| format.getSampleRate() == getSampleRate())
437
&& (format.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED
438
|| format.getSampleSizeInBits() == getSampleSizeInBits())
439
&& (format.getFrameRate() == (float)AudioSystem.NOT_SPECIFIED
440
|| format.getFrameRate() == getFrameRate())
441
&& (format.getFrameSize() == AudioSystem.NOT_SPECIFIED
442
|| format.getFrameSize() == getFrameSize())
443
&& (getSampleSizeInBits() <= 8
444
|| format.isBigEndian() == isBigEndian())) {
445
return true;
446
}
447
return false;
448
}
449
450
/**
451
* Returns a string that describes the audio format, such as: "PCM SIGNED
452
* 22050 Hz 16 bit mono big-endian". The contents of the string may vary
453
* between implementations of Java Sound.
454
*
455
* @return a string representation of the audio format
456
*/
457
@Override
458
public String toString() {
459
String sampleRate = getSampleRate() == AudioSystem.NOT_SPECIFIED ?
460
"unknown sample rate" : getSampleRate() + " Hz";
461
462
String sampleSize = getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED ?
463
"unknown bits per sample" : getSampleSizeInBits() + " bit";
464
465
String channels = switch (getChannels()) {
466
case 1 -> "mono";
467
case 2 -> "stereo";
468
case AudioSystem.NOT_SPECIFIED -> "unknown number of channels";
469
default -> getChannels() + " channels";
470
};
471
472
String frameSize = getFrameSize() == AudioSystem.NOT_SPECIFIED ?
473
"unknown frame size" : getFrameSize() + " bytes/frame";
474
475
String frameRate = "";
476
if (Math.abs(getSampleRate() - getFrameRate()) > 0.00001) {
477
frameRate = getFrameRate() == AudioSystem.NOT_SPECIFIED ?
478
", unknown frame rate":", " + getFrameRate() + " frames/second";
479
}
480
481
String bigEndian = "";
482
if ((getEncoding().equals(Encoding.PCM_SIGNED)
483
|| getEncoding().equals(Encoding.PCM_UNSIGNED))
484
&& ((getSampleSizeInBits() > 8)
485
|| (getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED))) {
486
bigEndian = isBigEndian() ? ", big-endian" : ", little-endian";
487
}
488
489
return String.format("%s %s, %s, %s, %s%s%s", getEncoding(),
490
sampleRate, sampleSize, channels, frameSize,
491
frameRate, bigEndian);
492
}
493
494
/**
495
* The {@code Encoding} class names the specific type of data representation
496
* used for an audio stream. The encoding includes aspects of the sound
497
* format other than the number of channels, sample rate, sample size, frame
498
* rate, frame size, and byte order.
499
* <p>
500
* One ubiquitous type of audio encoding is pulse-code modulation (PCM),
501
* which is simply a linear (proportional) representation of the sound
502
* waveform. With PCM, the number stored in each sample is proportional to
503
* the instantaneous amplitude of the sound pressure at that point in time.
504
* The numbers may be signed or unsigned integers or floats. Besides PCM,
505
* other encodings include mu-law and a-law, which are nonlinear mappings of
506
* the sound amplitude that are often used for recording speech.
507
* <p>
508
* You can use a predefined encoding by referring to one of the static
509
* objects created by this class, such as {@code PCM_SIGNED} or
510
* {@code PCM_UNSIGNED}. Service providers can create new encodings, such as
511
* compressed audio formats, and make these available through the
512
* {@link AudioSystem} class.
513
* <p>
514
* The {@code Encoding} class is static, so that all {@code AudioFormat}
515
* objects that have the same encoding will refer to the same object (rather
516
* than different instances of the same class). This allows matches to be
517
* made by checking that two format's encodings are equal.
518
*
519
* @author Kara Kytle
520
* @see AudioFormat
521
* @see javax.sound.sampled.spi.FormatConversionProvider
522
* @since 1.3
523
*/
524
public static class Encoding {
525
526
/**
527
* Specifies signed, linear PCM data.
528
*/
529
public static final Encoding PCM_SIGNED = new Encoding("PCM_SIGNED");
530
531
/**
532
* Specifies unsigned, linear PCM data.
533
*/
534
public static final Encoding PCM_UNSIGNED = new Encoding("PCM_UNSIGNED");
535
536
/**
537
* Specifies floating-point PCM data.
538
*
539
* @since 1.7
540
*/
541
public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
542
543
/**
544
* Specifies u-law encoded data.
545
*/
546
public static final Encoding ULAW = new Encoding("ULAW");
547
548
/**
549
* Specifies a-law encoded data.
550
*/
551
public static final Encoding ALAW = new Encoding("ALAW");
552
553
/**
554
* Encoding name.
555
*/
556
private final String name;
557
558
/**
559
* Constructs a new encoding.
560
*
561
* @param name the name of the new type of encoding
562
*/
563
public Encoding(final String name) {
564
this.name = name;
565
}
566
567
/**
568
* Indicates whether the specified object is equal to this encoding,
569
* returning {@code true} if the objects are equal.
570
*
571
* @param obj the reference object with which to compare
572
* @return {@code true} if the specified object is equal to this
573
* encoding; {@code false} otherwise
574
*/
575
@Override
576
public final boolean equals(final Object obj) {
577
if (this == obj) {
578
return true;
579
}
580
if (!(obj instanceof Encoding)) {
581
return false;
582
}
583
return Objects.equals(name, ((Encoding) obj).name);
584
}
585
586
/**
587
* Returns a hash code value for this encoding.
588
*
589
* @return a hash code value for this encoding
590
*/
591
@Override
592
public final int hashCode() {
593
return name != null ? name.hashCode() : 0;
594
}
595
596
/**
597
* Returns encoding's name as the string representation of the encoding.
598
* For the predefined encodings, the name is similar to the encoding's
599
* variable (field) name. For example, {@code PCM_SIGNED.toString()}
600
* returns the name "PCM_SIGNED".
601
*
602
* @return a string representation of the encoding
603
*/
604
@Override
605
public final String toString() {
606
return name;
607
}
608
}
609
}
610
611