Cubix, 16 bytes
$-!u'HIa'@/1@O<
Net form:
$ -
! u
' H I a ' @ / 1
@ O < . . . . .
. .
. .
Try it yourself
You should input the file decimal byte values in a separated list. The separator doesn't matter, anything that is not a digit or a minus sign suffices. The code really only cares about the first byte, so you can leave out the rest of the file if you like. The program outputs 0
for lossless, and 1
for lossy. Try it here! The default input uses a FLAC header.
Explanation
The nice thing about files is that (nearly) all of them have a so-called magic. Those are the first few bytes of the file. Good software doesn't check the file extension, but rather the file magic to see if it can handle a certain file.
Dennis has found a way to use this magic to find the compression type, but the fact that he discarded the first byte made me want to try to come up with a method that used the first byte, rather than the second. After all, this community is all about saving bytes.
Here's a list of the first bytes of the different file types. I ordered them into two groups: lossy and lossless. Here are the values of their first byte in decimal, hexadecimal and binary. You might see a pattern already...
Lossy: Lossless:
255:0xFF:0b11111111 102:0x66:0b01100110
79:0x4F:0b01001111 84:0x54:0b01010100
35:0x23:0b00100011 82:0x52:0b01010010
11:0x0B:0b00001011 70:0x46:0b01000110
0:0x00:0b00000000
The pattern I saw, was that the second bit (counted from left to right) was always on on the "lossless" bytes and the fifth bit was always off. This combination does not appear in any of the lossy formats. To "extract" this, we would simply do a binary AND (by 0b01001000 (=72)
) and then compare to 0b01000000 (=64)
. If both are equal, the input format is lossless, otherwise it's lossy.
Sadly, Cubix doesn't have such a comparison operator, so I used subtraction (if the result is 64, this yields 0, and it results in 8, -56 or -64 otherwise. I'll get back to this later.
First, let's start at the beginning of the program. The binary AND is done using the a
command:
'HIa
'H # Push 0b01001000 (72)
I # Push input
a # Push input&72
Then, we compare to 64 using subtraction (note we hit a mirror that reflects the IP to the top face [first line, second character, pointing south] in the middle of this part).
'@-
'@ # Push 0b01000000 (64)
- # Subtract from (input&72)
# Yields 0 for lossy, non-zero otherwise
After the IP is turned around by the u
, we use some control flow to push a 1
to the stack if (and only if) the top of the stack is non-zero:
!$1
! # if top = 0:
$1 # do nothing
# else:
1 # push 1
After we wrap around the cube, we hit the <
instruction, which points the IP west on the fourth line. All that's left to do is output and terminate.
O@
O # Output top of the stack as number
@ # End program
So, the program outputs 0
for lossless, and 1
for lossy.
"AAC audio in a MPEG Layer 4 container" raises the question: what other container formats do answers need to handle? – Peter Taylor – 2017-04-15T11:54:42.860
@PeterTaylor Only AAC was given special mention because I couldn't find a way to provide AAC audio without embedding it in an MPEG Layer 4 container via FFMPEG. The Vorbis audio is embedded in an Ogg container (as is the norm for Vorbis audio). All others are standalone formats. – Mego – 2017-04-15T18:32:47.547
Are you sure about the TTA file? According to the spec, TTA files should start with the magic number TTA1 or TTA2. FFM2 (the magic number of your file) appears to correspond to FFmpeg stream. Linux file recognizes the TTA1 header, but not the FFM2 one.
– Dennis – 2017-04-27T14:49:11.647Also, can we assume that AAC will always be in an MPEG Layer 4 header? If not, what can we assume? – Dennis – 2017-04-27T15:16:43.037
Can we take the contents of the file as an input or does our code have to retrieve them? – Shaggy – 2017-04-27T16:31:25.023
@Shaggy The contents may be piped in, or taken as a filename/URL or any of the other default I/O methods, so long as no additional input is used. – Mego – 2017-04-27T20:18:21.480
Would my 20 byte solution, so? Sorry, I'm still learning all the rules & standards around here. – Shaggy – 2017-04-28T10:09:56.457
@Shaggy It appears valid to me. – Mego – 2017-04-28T10:10:37.680
Sweet, thanks, @Mego :) – Shaggy – 2017-04-28T10:11:07.863