Skip to content

Add AIFF-C subformats for twos,in24,in32,42ni,23ni#916

Open
madah81pnz1 wants to merge 3 commits into
xiph:masterfrom
madah81pnz1:add-more-aiff-c-formats
Open

Add AIFF-C subformats for twos,in24,in32,42ni,23ni#916
madah81pnz1 wants to merge 3 commits into
xiph:masterfrom
madah81pnz1:add-more-aiff-c-formats

Conversation

@madah81pnz1

Copy link
Copy Markdown
Contributor

Added new option --force-aiff-c-format=FORMAT

Added new option --force-aiff-c-format=FORMAT
Comment thread src/flac/encode.c
; /* nothing to do, we already default to big-endian */
}
else {
flac__utils_printf(stderr, 1, "%s: ERROR: can't handle AIFF-C compression type \"%c%c%c%c\"\n", e->inbasefilename, (char)(xx>>24), (char)((xx>>16)&8), (char)((xx>>8)&8), (char)(xx&8));

@madah81pnz1 madah81pnz1 Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This & 8 seems to be a very old bug, all the way from the original implementation in 2005 (commit 15acb69).
It would print either a NUL character or a BS (backspace) character.

I added get_printable_char() to avoid printing garbage characters to the terminal or log file, as this could potentially be exploited in some way wit, e.g. unicode right-to-left override or escape sequence.

Comment thread src/test_streams/main.c
if(!generate_unsigned_raw(fn, channels, bits_per_sample/8, nsamples[samples]))
return 1;
if(bits_per_sample <= 24) {
/* unsigned 32 bps raw does not work */

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The raw unsigned test fails for 32 bits per sample. Note that I increased it to 32 and the max value tested was only up to 24 before.

Comment thread man/flac.md Outdated
: Instruct the decoder to output an AIFF-C file with format NONE and
sowt respectively.

**\--force-aiff-c-format**={none\|sowt\|twos\|in24\|42ni\|in32\|23ni}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other format types would be 'raw ', but seems to be very rarely used.

'in16'/'61ni' is another one for 16-bit audio, which seems to be used only internally in CoreAudio, but very rarely in actual AIFF-C files.

@H2Swine

H2Swine commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

raw is 8-bit signed. Easily produced with ffmpeg -c:a copy , and to those who are not aware the signedness of every format, it could very well show up. I would suppose it isn't hard to handle, but that _en_coding support might be more interesting.

@madah81pnz1

Copy link
Copy Markdown
Contributor Author

raw is 8-bit signed. Easily produced with ffmpeg -c:a copy , and to those who are not aware the signedness of every format, it could very well show up. I would suppose it isn't hard to handle, but that _en_coding support might be more interesting.

I had it initially, but decided to not include it, due to it being rare, and its endianess is ambigious beyond 8 bits.
It's easy to add back, but then I think I'll restrict it to 8 bits only, same as 'in24' is restricted to 24 bits only.

You have to have both encode and decode support, otherwise foreign metadata is not able to restore the original file back.

@madah81pnz1

Copy link
Copy Markdown
Contributor Author

raw is 8-bit signed. Easily produced with ffmpeg -c:a copy , and to those who are not aware the signedness of every format, it could very well show up. I would suppose it isn't hard to handle, but that _en_coding support might be more interesting.

But I realized now this contradicts the findings here: https://hydrogenaudio.org/index.php/topic,127436.25.html
afconvert with -d UI8 will write 'raw ' as unsigned 8-bit, not signed?

If flac is going to support 'raw ', it should be unsigned then, to atleast keep in sync with afconvert. I can push another commit with these changes.

The problem then becomes if there is ever a need to support both signed and unsigned for 'raw '. If so that means flac must store some additional metadata, since there is nothing itself in the AIFF-C format (and flac's foreign metadata of it) that can recover the signedness of the audio.

@H2Swine

H2Swine commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

1: you are right I was dumb, 2: what about ... something that does the bit depth for the user?

raw is 8-bit signed.

But I realized now this contradicts the findings here: https://hydrogenaudio.org/index.php/topic,127436.25.html afconvert with -d UI8 will write 'raw ' as unsigned 8-bit, not signed?

Thanks for arresting thoughtless swiney me being too dumb to think twice. raw is 8-bit unsigned like WAVE 8-bit (but unlike the traditional AIFF which like AU/SND writes 8-bit as signed).
Yeah, treat it as "8 bits only".

.

  1. Here is the problem: User needs to know the bit depth, and that is unnecessary. Consider instead:
    --force-aiff-c-format=in and --force-aiff-c-format=ni or
    --force-aiff-c-in-format and --force-aiff-c-ni-format without options.
    Let the decoder put in 24/42 etc, and in help file explain that "in" means the trad-AIFF endian with new type designations that Apple seems to write, while "ni" means WAVE endian (unsigned 'raw' in case of 8-bit).

Also, what is the capitalization in the AIFF files?

@madah81pnz1

Copy link
Copy Markdown
Contributor Author
2. Here is the problem: User needs to know the bit depth, and that is unnecessary. Consider instead:
   `--force-aiff-c-format=in` and `--force-aiff-c-format=ni` or
   `--force-aiff-c-in-format` and `--force-aiff-c-ni-format` without options.
   Let the decoder put in 24/42 etc, and in help file explain that "in" means the trad-AIFF endian with new type designations that Apple seems to write, while "ni" means WAVE endian (unsigned 'raw' in case of 8-bit).

Yes, it is a good idea. I was more thinking of a =le and =be syntax, since it is not obvious what =ni and =in stands for.
An example:

8 16 24 32 others
in NONE NONE in24 in32 NONE
ni sowt sowt 42ni 23ni sowt
  • = any other bit depth, e.g. 20 bits

But then what if you want 'twos' instead of 'NONE'? And 'raw ' for 8 bit, or if you don't want 'raw '. Seems we need some kind of profile mapping for this, e.g. a list of preferred AIFC compression types and what bits they should be used for.
This is why I opted to not do this as part of this commit, just add support as a first step and then see how it pans out.

(There's also 'in16'/'61ni' for 16-bits, but I don't want to promote or make flac legitimate its usage further.)

Also, what is the capitalization in the AIFF files?

Only 'NONE' is upper-case, everything else is (supposedly) lower-case.
But then for other formats such as 'fl32', 'ulaw' and 'alaw', it seems common to also handle 'FL32', 'ULAW' and 'ALAW' as the same. https://www.mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html

@H2Swine

H2Swine commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Uh-oh, stop press. According to https://developer.apple.com/documentation/avfaudio/avaudiocommonformat/pcmformatint16
, "in" is native endianness, not big endian.

QuickTime doc does not cite endianness for these. It does for twos and sowt. Of course when https://developer.apple.com/standards/qtff-2001.pdf was issued, endianness would default to Big. But now there is a source saying native. Also here is how ffmpeg mishandled little-endian in24 in .mov. Of course AIFC lacks the QuickTime format's endianness atom: https://trac.ffmpeg.org/ticket/1881

This found by asking AI engines to get a pseudo-confirmation on what is supposed to be right about 8-bit ... this was a byproduct.

@madah81pnz1

Copy link
Copy Markdown
Contributor Author

Uh-oh, stop press. According to https://developer.apple.com/documentation/avfaudio/avaudiocommonformat/pcmformatint16 , "in" is native endianness, not big endian.

QuickTime doc does not cite endianness for these. It does for twos and sowt. Of course when https://developer.apple.com/standards/qtff-2001.pdf was issued, endianness would default to Big. But now there is a source saying native. Also here is how ffmpeg mishandled little-endian in24 in .mov. Of course AIFC lacks the QuickTime format's endianness atom: https://trac.ffmpeg.org/ticket/1881

This found by asking AI engines to get a pseudo-confirmation on what is supposed to be right about 8-bit ... this was a byproduct.

An interesting point. When ffmpeg does a codec copy, does it also retain the 'enda' chunk? So you could for example have two .mov files with 'in24', and 'enda' specified as little-endian in one and big-endian in the other. A plain codec copy would copy the data as-is, but one file would for sure be interpreted wrongly in most (if not all) players and software. Unless ffmpeg switches from 'in24' to '42ni' for one file?

The main purpose of doing this in flac is to increase interoperability with existing tools (e.g. sox, ffmpeg, libsndfile), and if they all agree that 'in24' is big-endian and '42ni' is little-endian, then that problem is solved, as it has already become the de facto standard way to write AIFF-C files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants