randomNumber71 hour ago
What is the purpose of this and how would I use it (as someone who actually knows a lot about music theory and C programming)?
lowsun1 hour ago
Well, this library provides the core functions for classical, Western music theory (scales, keys, intervals, etc.). So any ideas that needs to understand or generate these structures could use them. Some examples off the top of my head:

- Music theory education tools - Music generation (and the outputs could be transformed to MIDI format for example) - Piano chord finder

and similar.

randomNumber71 hour ago
So you can generate the d dorian scale and it outputs d e f g a b c d?

Whats the target audience? A good musician knows the scales by heart (and also how they sound/feel) and for the others it's unclear to me what they would do with music theory they don't really understand.

lowsun1 hour ago
There is a function for that, yes.

For your second thought, I'm not really sure I understand the point.

Since this is a library, it can power any application that needs to understand or generate these abstractions. So to expand on some options I gave above:

- You can create a program that generates a piece in the style of a Bach cantata for example, using this library as the backbone.

- If a teacher wanted to create a tool to educate kids about scales for example, it can use this library as a backbone.

pipeline_peak1 hour ago
>So you can generate the d dorian scale and it outputs d e f g a b c d?

lmao

OptionOfT7 hours ago
As someone who only has used C in conjunction with Rust...

Given that it is 2026, what are some of the thoughts that go into choosing C99 vs C23, which I presume has more quality-of-life features?

jcalvinowens5 hours ago
Requiring C23 for a library header is a great way to guarantee nobody will use your code for long time.

I still write nearly ANSI compliant C for simple embedded things. Because somebody might need to figure out how to rebuild it in twenty years, and making that person's life harder for some syntactic sugar isn't worth it.

Even C99 can be a problem: for example, C99 designated initializers are not supported in C++. If your header needs to support C++ you can't use them (C++ forces you to initialize every field in the structure in order if you do it that way).

rabf6 hours ago
Very few people are using C for `quality-of-life features`. I'm fairly certain I've never even seen any C23 code, is it supported by many compilers or C tooling? One of the great things about C is that it is fairly easy to write code that runs everywhere and for a library that is especially important. There are many who just stick to C89.
fallingmeat6 hours ago
known quantity. UBs well understood. tooling.
ceteia3 hours ago
Nitpicking:

https://github.com/thelowsunoverthemoon/mahler.c/blob/4ebfe8...

Should that type have been mah_acci instead of int? mah_acci doesn't seem to be used anywhere.

Also, have you considered using (edit) designated initializer syntax for some of the function calls that take in structs as arguments?

https://cppreference.com/w/c/language/struct_initialization....

    struct mah_scale scale = mah_get_scale(
        (struct mah_note) {
            .tone=MAH_C,
            .acci=MAH_NATURAL,
            .pitch=4
        },
        &MAH_BLUES_SCALE, notes,
        MAH_ASCEND,
        NULL
    );
lowsun3 hours ago
Ah yes, that is by design. This is because it supports more than a double sharp / double flat (eg triple sharp, quad sharp, etc). The enums are there just for the most common values so it's easier to read.

As for second, that's a good point! Would definitely make readability better, thanks.