From: David ‘Bombe’ Roden Date: Sun, 2 Jun 2013 00:11:33 +0000 (+0200) Subject: Supply the frame’s content. X-Git-Url: https://git.pterodactylus.net/?p=sonitus.git;a=commitdiff_plain;h=ed7b4e864c29bbf8b5d1a394c1d41f23a3394e27 Supply the frame’s content. --- diff --git a/src/main/java/net/pterodactylus/sonitus/io/mp3/Frame.java b/src/main/java/net/pterodactylus/sonitus/io/mp3/Frame.java index ad91a91..b157e2c 100644 --- a/src/main/java/net/pterodactylus/sonitus/io/mp3/Frame.java +++ b/src/main/java/net/pterodactylus/sonitus/io/mp3/Frame.java @@ -17,6 +17,7 @@ package net.pterodactylus.sonitus.io.mp3; +import java.util.Arrays; import java.util.Map; import com.google.common.base.Optional; @@ -215,6 +216,9 @@ public class Frame { /** The decoded emphasis mode. */ private final int emphasis; + /** The content of the frame. */ + private final byte[] content; + /** * Creates a new frame from the given values. * @@ -243,7 +247,7 @@ public class Frame { * @param emphasis * The emphasis */ - private Frame(int mpegAudioVersionId, int layerDescription, int protectionBit, int bitrateIndex, int samplingRateFrequencyIndex, int paddingBit, int privateBit, int channelMode, int modeExtension, int copyrightBit, int originalBit, int emphasis) { + private Frame(int mpegAudioVersionId, int layerDescription, int protectionBit, int bitrateIndex, int samplingRateFrequencyIndex, int paddingBit, int privateBit, int channelMode, int modeExtension, int copyrightBit, int originalBit, int emphasis, byte[] content) { this.mpegAudioVersionId = mpegAudioVersionId; this.layerDescription = layerDescription; this.protectionBit = protectionBit; @@ -256,6 +260,7 @@ public class Frame { this.copyrightBit = copyrightBit; this.originalBit = originalBit; this.emphasis = emphasis; + this.content = content; } // @@ -363,6 +368,15 @@ public class Frame { return Emphasis.values()[emphasis]; } + /** + * Returns the content of this frame. + * + * @return The content of this frame + */ + public byte[] content() { + return content; + } + // // STATIC METHODS // @@ -384,6 +398,33 @@ public class Frame { } /** + * Calculates the frame length in bytes for the frame starting at the given + * offset in the given buffer. This method should only be called for a buffer + * and an offset for which {@link #isFrame(byte[], int, int)} returns {@code + * true}. + * + * @param buffer + * The buffer storing the frame + * @param offset + * The offset of the frame + * @return The length of the frame in bytes, or {@code -1} if the frame length + * can not be calculated + */ + public static int getFrameLength(byte[] buffer, int offset) { + MpegAudioVersion mpegAudioVersion = MpegAudioVersion.values()[(buffer[offset + 1] & 0x18) >>> 3]; + LayerDescription layerDescription = LayerDescription.values()[(buffer[offset + 1] & 0x06) >>> 1]; + int bitrate = bitrateSupplier.get().get(mpegAudioVersion).get(layerDescription).get((buffer[offset + 2] & 0xf0) >>> 4) * 1000; + int samplingRate = samplingRateSupplier.get().get(mpegAudioVersion).get((buffer[offset + 2] & 0x0c) >>> 2); + int paddingBit = (buffer[offset + 2] & 0x02) >>> 1; + if (layerDescription == LayerDescription.LAYER_1) { + return (12 * bitrate / samplingRate + paddingBit) * 4; + } else if ((layerDescription == LayerDescription.LAYER_2) || (layerDescription == LayerDescription.LAYER_3)) { + return 144 * bitrate / samplingRate + paddingBit; + } + return -1; + } + + /** * Tries to create an MPEG audio from the given data. * * @param buffer @@ -409,7 +450,8 @@ public class Frame { int copyright = (buffer[offset + 3] & 0x08) >> 3; int original = (buffer[offset + 3] & 0x04) >> 2; int emphasis = buffer[offset + 3] & 0x03; - return Optional.of(new Frame(mpegAudioVersionId, layerDescription, protectionBit, bitrateIndex, samplingRateFrequencyIndex, paddingBit, privateBit, channelMode, modeExtension, copyright, original, emphasis)); + int frameLength = getFrameLength(buffer, offset); + return Optional.of(new Frame(mpegAudioVersionId, layerDescription, protectionBit, bitrateIndex, samplingRateFrequencyIndex, paddingBit, privateBit, channelMode, modeExtension, copyright, original, emphasis, Arrays.copyOfRange(buffer, 4, frameLength))); } return Optional.absent(); } diff --git a/src/main/java/net/pterodactylus/sonitus/io/mp3/Parser.java b/src/main/java/net/pterodactylus/sonitus/io/mp3/Parser.java index 55165d8..bbdb5a3 100644 --- a/src/main/java/net/pterodactylus/sonitus/io/mp3/Parser.java +++ b/src/main/java/net/pterodactylus/sonitus/io/mp3/Parser.java @@ -93,9 +93,17 @@ public class Parser { } System.arraycopy(buffer, 1, buffer, 0, 3); buffer[3] = (byte) r; - Optional frame = Frame.create(buffer, 0, 4); - if (frame.isPresent()) { - return frame.get(); + if (Frame.isFrame(buffer, 0, 4)) { + int frameLength = Frame.getFrameLength(buffer, 0); + if (frameLength != -1) { + byte[] content = new byte[frameLength + 4]; + readFully(inputStream, content, 4, frameLength); + System.arraycopy(buffer, 0, content, 0, 4); + Optional frame = Frame.create(content, 0, frameLength + 4); + if (frame.isPresent()) { + return frame.get(); + } + } } } }