4 ms·
static inline int qoa_clamp_s16(int v) { if ((unsigned int)(v + 32768) > 65535) { ... } This code is wrong. It assumes int is at least 32-bit whi
by kevin_thibedeau 4y ago
static inline int qoa_clamp_s16(int v) {
if ((unsigned int)(v + 32768) > 65535) {
...
}
This code is wrong. It assumes int is at least 32-bit which is not true in C. It should either use long or int32_t.
- vardump 4y agoYeah. Bitten me not-too-long-ago...
- ReactiveJelly 4y agoIt's also odd that everything is big-endian, but then the official format is C structures (which will be LE on every PC and phone that would ever run this) And in that C struct.... is `char` and also `uint8_t`. I can never remember if `char` is signed or not. It should be `int8_t` or `uint8_t`. This reminds me of the Farbfeld image format. So simple that I'm content to just make my own little-endian ad-hoc implementation and ignore the official spec.
- kevin_thibedeau 4y ago> I can never remember if `char` is signed or not. char is effectively a trivalent type. Only use it when signedness is inconsequential. This is addressed in C23 with char8_t expressly to avoid the problems that happen with UTF-8 bytes as accidental signed chars.
- audunw 4y ago> which will be LE on every PC and phone that would ever run this Why would you want to run this on a modern high end PC or phone? There's almost no point using a simple codec like this if you have the computing resources or dedicates hardware to use a "proper" codec. The codec is probably a reasonable choice for a microcontroller where you do want to save memory but you barely have CPU cycles to process the audio data. Many microcontrollers are big endian.
- makapuf 4y agoSure there is lore diversity in microcontrollers and there are bog endians but much more are or can ne configured as little endian ARM, riscv, avr, mips, msp430 ..
- flohofwoe 4y agoFor cross-platform 'gamey code' (e.g. game jam stuff or smaller indie games), having an audio file format which is very simple to load and decode in your own code without having to use the plethora of platform-specific audio decoder APIs, or having to integrate decoder libraries with often questionable API design choices (which is often a challenge of its own) has a lot of advantages. Same arguments for using the Quite OK Image Format over things like PNG or JPEG for instance (although since stb_image.h this isn't such a big issue anymore).
- electroly 4y agoYour post: "Why would you want to run this on a modern high end PC or phone?" Another post in the same thread: "In the real world, for this type of code ..., only a very small number of CPUs (Intel and ARM) and C compilers (Clang, GCC and MSVC) matter ..." These posts are strongly disagreeing with each other but neither of you directly replied to the other, so I'm not sure if you've seen it. I'm replying to you because I think, between the two of you, you're the one that's wrong and the other poster is right. The original announcement doesn't mention microcontrollers at all and does mention computer games[1]. Further, their defense for the endianness decision was simply that they like it, rather than that they expect any target CPU to be big endian. I think GP is right--this will almost never be run on a big endian CPU. Indeed, the start of this thread was a piece of code that won't work at all on smaller microcontrollers. I think it's likely this code has never been run on a microcontroller. [1] https://phoboslab.org/log/2023/02/qoa-time-domain-audio-compression https://phoboslab.org/log/2023/02/qoa-time-domain-audio-comp...
- flohofwoe 4y ago> I can never remember if `char` is signed or not. Technically it's neither (e.g 'char', 'signed char' and 'unsigned char' are three different types), but in practice this also usually doesn't matter (but it's more likely to be bitten by this specific detail than int not being 32 bits).
- flohofwoe 4y agoThat might be true in theory, but not relevant in practice unless you're on a really old or really esoteric CPU (one could extend that to: the C standard is important in theory, but usually not relevant in practice - the only thing that matters in the real world is how specific C compilers behave). In the real world, for this type of code (audio code, most likely for games), only a very small number of CPUs (Intel and ARM) and C compilers (Clang, GCC and MSVC) matter, and on those, int is 32 bits wide. PS: For new code I would also suggest using the "new" C99 fixed-width integer types though.
- ant6n 4y agoBut what about the game boy!
- minimaul 4y agoI think you’re okay there, the Game Boy doesn’t have any sound output channel this could work with anyway :)
- ant6n 4y agoHe does, too! https://problemkaputt.de/pandocs.htm#soundchannel3waveoutput https://problemkaputt.de/pandocs.htm#soundchannel3waveoutput
- minimaul 4y agoI was aware of this, but I don't think a 32 sample 4-bit wave RAM is quite good enough to make something representative :)
- ant6n 4y agoIt's possible to play ~8KHz+ 4bit PCM. Just need to update the wave RAM four times per frame using an hblank interrupt handler. Or write completely deterministic code that unpacks the audio and writes it out at the correct time intervals.