diff options
-rw-r--r-- | .clang-format | 65 | ||||
-rw-r--r-- | .gitattributes | 1 | ||||
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | LICENSE | 19 | ||||
-rw-r--r-- | README | 118 | ||||
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | build_and_test.sh | 132 | ||||
-rw-r--r-- | refetch_deps.sh | 1 | ||||
-rw-r--r-- | source/tests/_static.c | 1 | ||||
-rw-r--r-- | source/tests/main.test.c | 1 |
10 files changed, 346 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6df0ff7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,65 @@ +BasedOnStyle: LLVM +UseTab: Never +TabWidth: 2 +IndentWidth: 2 + +Language: Cpp +Standard: Auto + +ColumnLimit: 70 +MaxEmptyLinesToKeep: 1 +SpacesBeforeTrailingComments: 1 +AccessModifierOffset: -2 +PenaltyBreakAssignment: 100 +PenaltyReturnTypeOnItsOwnLine: 200 + +IndentCaseLabels: true +IndentExternBlock: NoIndent +IndentGotoLabels: false +IndentPPDirectives: AfterHash +IndentRequires: true +IndentWrappedFunctionNames: false +NamespaceIndentation: All + +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: true +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInSquareBrackets: false + +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: Consecutive +AlignConsecutiveBitFields: Consecutive +AlignConsecutiveDeclarations: Consecutive +AlignEscapedNewlines: Left +AllowShortLambdasOnASingleLine: All +AllowShortFunctionsOnASingleLine: Empty +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BreakBeforeConceptDeclarations: true +BreakConstructorInitializers: AfterColon +Cpp11BracedListStyle: false +EmptyLineBeforeAccessModifier: LogicalBlock +FixNamespaceComments: false +PointerAlignment: Right +ReflowComments: true +SortIncludes: Never +SortUsingDeclarations: true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66a8a0b --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/*build*/ +/source/kit/ +/source/stb/ +/source/sokol/ +/source/nanovg/ +/source/miniaudio/ +*.swp @@ -0,0 +1,19 @@ +Copyright (c) 2023 Mitya Selivanov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. @@ -0,0 +1,118 @@ +Music sequencer and audio editor + + +Tech + +- kit - https://guattari.tech/kit.git +- sokol_app - https://github.com/floooh/sokol.git +- nanovg - https://github.com/memononen/nanovg.git +- miniaudio - https://github.com/mackron/miniaudio.git +- portmidi - https://github.com/PortMidi/portmidi.git + + +Algorithms + +- Cooley-Tukey FFT +- Biquad filter + + +Primary design + + +Basic UI + +- Bus list +- Bus units +- Track editor +- Sheet editor + ++---------+ +-----------------------------------+ +-[ Bus A ]-------+ +[+]Bus A ^ | [ track 1 ====== ] ^ [+] Arpeggiator ^ +|---------| | | | [x] ** *** | +[+]Bus B | | [ track 2 ============== ] | | [ ] <--> ++ | +|---------| | | |-----------------| +[+]Master v | v [+] Synth | +[+]-------+ +<--------------------------------->+ | ^ ^ ^ [ ] | + | / \ / \ / [x] | ++----[ track 2 ]--------------------------------+ | V V [o] | +|F > ^ |-----------------| +|E > x x x x x | [+] Reverb | +|D > x x x x x | | <-----> [x] [u] | +|C > x x x x x x x v | v ++--|<------------------------------------------>+ [+]---------------+ + + +Modularity + +Music and audio features will be implemented as a separate library with no external dependencies. +UI and audio devices will be distinct modules which can be replaced. + + +Sheet data + + /---------------------\ + | | + | Note | + | | + | time : i64 | + | duration : i64 | + | frequency : f64 | + | amplitude : f64 | + | flavor : f64 | + | | + \---------------------/ + +Unlike MIDI, we will allow to set any floating-point value for the note frequency. +Time is defined as a sample index and therefore is relative to the sample rate. + + +Processing + +A unit is a processing entity. + + for each unit: + output[channel, time] = eval(inputs, channel, sample_rate, time) + +Unlike VST, time for a processing routine is one of explicit parameters. +The processing routine can access any samples of inputs. +This approach allows to evaluate samples non-sequentially, and even do some tricks like time-reverse effects. +Changing the sample rate is also quite simple. + + +Global matrix + + /---------------------------\ + | Matrix | + | | + | (connections data) | + | A.out[0] -> B.in[0] |-----------------+ + | B.out[0] -> Master.in[0] |----------------+| + | B.out[1] -> Master.in[1] | || + \---------------------------/ || + ^ | ^^ ||(in[0], in[1]) + | | || || + | | ||(out[0], out[1]) vv +/----------\ | | /----------\ /-----------\ +| Module A |---+ +-->| Module B | | Master | +| (sheet) | (out[0]) (in[0]) | (synth) | | (limiter) | +\----------/ \----------/ \-----------/ + +The global matrix manages the information about connections between units. +Each unit can communicate to others through the global matrix. +Each unit can have inputs and outputs for sheet and signal channels. + +To get data from a producing unit, the receiving unit will request the data from the global matrix using the input index. +The global matrix will resolve the producing unit by input index, and request data from it. +The evaluation startes from the master and gradually reaches all required units. + + +Global modifiers + +Special units can affect all regular units, filtered by some criteria. +This will allow to do some global changes, e.g. change the musical scale of the entire composition. + + +Customization + +In the matrix mode, any inputs and outputs can be connected. +A custom unit can be created with code editor and JIT-compilation. @@ -0,0 +1 @@ + diff --git a/build_and_test.sh b/build_and_test.sh new file mode 100644 index 0000000..5a96b0a --- /dev/null +++ b/build_and_test.sh @@ -0,0 +1,132 @@ +if [ ! -d "build" ]; then + mkdir build +fi + +OS=Linux +COMPILE=gcc +OBJ_POSTFIX=.o +EXE_POSTFIX= +FLAGS= +FLAG_OBJ="-c -o " +FLAG_EXE="-o " +LINK_FLAGS= + +if [ "$2" = "gcc" ]; then + COMPILE=gcc +elif [ "$2" = "clang" ]; then + COMPILE=clang +elif [ "$2" = "msvc" ]; then + COMPILE=cl.exe + OBJ_POSTFIX=.obj + FLAG_OBJ="-c -Fo" + FLAG_EXE="-Fe" +elif [ "$2" != "" ]; then + echo "Unknown C compiler" + exit 1 +fi + +if [ "$2" != "" ]; then + if command -v $COMPILE >/dev/null 2>&1; then + echo "C compiler found" + else + echo "C compiler not found" + exit 1 + fi +fi + +case $(uname | tr '[:upper:]' '[:lower:]') in + *darwin*) + OS=macOS + if [ "$2" = "" ]; then + if command -v clang >/dev/null 2>&1; then + echo "C compiler found - Clang" + COMPILE=clang + elif command -v gcc >/dev/null 2>&1; then + echo "C compiler found - GCC" + else + echo "C compiler not found" + exit 1 + fi + fi + ;; + *msys*|*cygwin*|*mingw*|*nt*|*win*) + OS=Windows + EXE_POSTFIX=.exe + if [ "$2" = "" ]; then + if command -v cl.exe >/dev/null 2>&1; then + echo "C compiler found - MSVC" + COMPILE=cl.exe + OBJ_POSTFIX=.obj + FLAG_OBJ="-c -Fo" + FLAG_EXE="-Fe" + elif command -v gcc >/dev/null 2>&1; then + echo "C compiler found - GCC" + elif command -v clang >/dev/null 2>&1; then + echo "C compiler found - Clang" + COMPILE=clang + else + echo "C compiler not found" + exit 1 + fi + fi + if [ "$COMPILE" = "cl.exe" ]; then + LINK_FLAGS="Shlwapi.lib Advapi32.lib" + else + LINK_FLAGS="-lShlwapi -lAdvapi32" + fi + ;; + *) + if [ "$2" = "" ]; then + if command -v gcc >/dev/null 2>&1; then + echo "C compiler found - GCC" + elif command -v clang >/dev/null 2>&1; then + echo "C compiler found - Clang" + COMPILE=clang + else + echo "C compiler not found" + exit 1 + fi + fi + ;; +esac + +if [ "$COMPILE" = "gcc" ] || [ "$COMPILE" = "clang" ]; then + if [ "$1" = "release" ]; then + FLAGS="-O3" + elif [ "$COMPILE" = "gcc" ] && [ "$OS" != "Windows" ]; then + FLAGS="-O0 -fsanitize=undefined,address,leak" + elif [ "$OS" != "Windows" ]; then + FLAGS="-O0 -fsanitize=undefined,address" + else + FLAGS="-O0" + fi +else + if [ "$1" = "release" ]; then + FLAGS="-O2" + else + FLAGS="-Od" + fi +fi + +echo "" + +echo "Build saw_test_suite" +$COMPILE ${FLAGS} \ + ${FLAG_EXE}"build/saw_test_suite${EXE_POSTFIX}" \ + "source/tests/_static.c" \ + ${LINK_FLAGS} +if [ $? -ne 0 ]; then + exit 1 +fi + +echo "Run tests" +echo "" + +STATUS=0 + +./build/saw_test_suite +if [ $? -ne 0 ]; then + STATUS=1 +fi + +exit $STATUS diff --git a/refetch_deps.sh b/refetch_deps.sh new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/refetch_deps.sh @@ -0,0 +1 @@ + diff --git a/source/tests/_static.c b/source/tests/_static.c new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/source/tests/_static.c @@ -0,0 +1 @@ + diff --git a/source/tests/main.test.c b/source/tests/main.test.c new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/source/tests/main.test.c @@ -0,0 +1 @@ + |