1. 25 Sep, 2022 28 commits
    • Joel K. Pettersson's avatar
      Rename '.w' to '.r' & add plain additive AM & FM. · 7a33a82c
      Joel K. Pettersson authored
      Language changes:
       * Rename '.w' sub-subparameters to '.r'.
       * Add support for modulator lists directly under
         'a', 'f' and 'r', in addition to those under a
         '.r' subname. The newer ones, directly under a
         main parameter name, are handled more like the
         'p' modulators in that the modulator output is
         simply summed for use with the parameter value
         -- instead of, as with '.r', multiplied up and
         then mapped, to a range defined by two values.
      If both the additive main modulators and the '.r'
      modulators are used at the same time for the same
      parameter, then the '.r' result is applied first,
      the main modulator outputs then added afterwards.
      Add example scripts 'halfrect_ringmod.sau',
      Change log:
       - 2022-09-22: Rename '.w' to '.r'. Add additive AM & FM.
       - 2022-09-23: Rename '.r' to '.m'.
       - 2022-09-26: Rename '.m' to '.r'. Adjust 'S a' for main
    • Joel K. Pettersson's avatar
    • Joel K. Pettersson's avatar
    • Joel K. Pettersson's avatar
      Optimize generator idling. · 8781ca50
      Joel K. Pettersson authored
      Optimize generator idling, by checking
      the need before doing buffer clearing.
      Makes a big difference for idly silent
      long script, 'devtests/alarm-25m.sau',
      not for other current scripts however.
    • Joel K. Pettersson's avatar
      Add -v verbose option, rename version to -V. · d4a97f17
      Joel K. Pettersson authored
      Add a -v "Playing ..." printout in player.c.
      Change log:
       * 2022-07-08: Add -v, "Playing ..." printout.
             Rename old -v to -V.
       * 2022-07-09: Update man page.
       * 2022-07-16: Exclude new printout on -c use.
       * 2022-08-04: Revert, broke (excluded) -c and
             -p, which was a bug.
       * 2022-08-06: Tweak printout on -cv, now says
             "Checked ..." instead of "Playing ...".
    • Joel K. Pettersson's avatar
      Unify ';' and '\' syntax variations. Simplify newline rule. · e430e803
      Joel K. Pettersson authored
      Language changes:
       * Rename '\' with number to ';' with number. The same use.
       * Newlines in the top scope will no longer end the current
         step, handling now becoming more regular and permissive.
         (Previously, an exception to the rule was new sub-steps,
         allowed on the line after a linebreak. '\' was different
         and not included in that exception. Now top and subscope
         handling is more similar and should be less surprising.)
      (A previous idea for a new syntax was to change ';' to ',',
      but it looked less clear, prompting ';' to be added for end
      of step, at least as an optional step terminator. This take
      two simplifies, and keeps the spirit of, the older syntax.)
      Adjust style in some scripts, since ';;number' is now nicer
      to read. Also, rework 'examples/sounds/unnamed1.sau' a bit.
      Adjust parsing, no longer end steps
      at top level of script on newlines.
      Change log:
       * 2022-05-22: Rename ';' separator
             to ','. Add optional ';' for
             explicitly terminating step.
       * 2022-05-23: Tidy code. Write new
             'Scopes' section on this and
             further in 'doc/README.SAU'.
       * 2022-05-24: Adjust scripts more.
       * 2022-06-08: Rename ',' separator
             back to ';' (remove new ';')
             and rename '\' to ';' (where
             the presence or absence of a
             number selects the meaning).
             Editing in 'doc/README.SAU'.
    • Joel K. Pettersson's avatar
      Add and use SAU_Scanner_get_suffc(). · 959d1b28
      Joel K. Pettersson authored
      Change log:
       * 2022-06-22: Use new scanning method
             to ensure no conflict if adding
             more constant, suffix names. Edit doc.
       * 2022-07-11: Rebase after old syntax
             changes replaced. Suffix method
             is still useful for e.g. "t" literals.
    • Joel K. Pettersson's avatar
      Add more math functions & some constants. · 2765d858
      Joel K. Pettersson authored
      Rework math module & parser code to allow
      more types of math symbols than "name(x)"
      functions. Add a per-script-unit state to
      allow functions to have state, used for a
      random number generator using SplitMix64.
      Add functions:
       * sin(x), cos(x)
       * rand(), seed(x), time()
       * rint(x)
      Add constants:
       * mf, pi
      Update 'doc/README.SAU'.
      The current, limited syntax allows a seed
      function given a 0 return value, I found.
      No need to add a S parameter, or similar.
      To allow adding more functions, and still
      have a nice-enough -h math printout etc.,
      make help printouts break too-long lines.
      Add a 'devtests/random/rand-pm-ratio.sau'
      script (scripts in 'random/' don't give a
      reproducible result), and a constant seed
      version in 'examples/tests/'.
      Change log:
       * 2022-05-08: Changes to support and add
             num. expr. 'rand()' and 'seed(x)',
             and also 'pi', 'sin(x)', 'cos(x)'.
       * 2022-05-09: Add 'time()' function, and
             create test scripts with 'rand()'.
             Document the 'seed(x)' sensitivity
             to rounding errors in values used.
       * 2022-05-10: Future-proof 'time()' when
             large 64-bit integers are handled.
       * 2022-06-01: Add 'rint(x)' function, so
             arithmetic and rounding for random
             number can give integers in range.
       * 2022-06-11: Add constant 'mf' ~632 Hz.
       * 2022-06-23: Tweak 'engine_rumble.sau'.
       * 2022-06-26: Refactor scanner functions
             and add a few, fix subtle bugs for
             future usage, fix "func()" parsing
             with the new SAU_Scanner_skipws().
    • Joel K. Pettersson's avatar
      Support '-o -' audio to stdout with AU format header. · 15ef2213
      Joel K. Pettersson authored
      Unlike WAV, AU allows headers without a known length,
      making non-raw audio piping viable. Can be convenient
      for allowing some utilities to receive the audio with
      format (channels, srate, and more) already filled-in.
      Rework the old wavfile module to an expanded sndfile,
      with three formats, and endian conversion (needed for
      Of course, it's now possible to write AU files too by
      using "... -o - > file.au". But for now, no option to
      generally do that is added, -o mostly remaining a WAV
      output option.
      Update man page.
      Change log:
       * 2022-05-09: Support '-o-' audio to stdout with AU header.
       * 2022-06-01: Edit man page.
       * 2022-06-02: Doc & error printout change for completeness.
             Tidy player.c further.
             Rework README.md more.
    • Joel K. Pettersson's avatar
      Add '--mono' and '--stdout' cli options. · 999d1ddf
      Joel K. Pettersson authored
      To enable interfacing with programs that
      accept 16-bit audio through stdin, add a
      new --stdout option to send extra output
      to stdout, and reserve stdout for audio.
      Also add --mono to downmix audio to mono
      (done when converted from internal float
      buffers) and produce all outputs in mono
      formats. Halves size for stdout and WAV.
      Change log:
       * 2022-05-04: Add audio options '--mono' and '--stdout'.
             Change SAU_getopt() to allow parsing these.
             Implement '--mono' option, '--stdout' option.
             Disable use of stdout for printing on --stdout.
       * 2022-05-05: Tidy up and fix the remaining problems.
             Buffer and alternate doubly-done generation too
             on -r value unsupported by system audio. Ensure
             --stdout output is always parallel with system.
             Update README.md, man page, and usage notice.
       * 2022-05-06: Ensure all printouts use stderr, if
             not from -p without --stdout. Tidy use of printing
             stream check. Document use of stdout vs. stderr in
             man page.
       * 2022-05-07: Rename option-conscious print to SAU_printf().
    • Joel K. Pettersson's avatar
      Improve number reading precision and make stricter. · bbde953b
      Joel K. Pettersson authored
      Rework SAU_File_getd() to have less rounding error,
      at very small size and speed cost. It is still less
      rigorous (and far simpler) than system strtod() and
      it still restricts how numbers can be written more.
      Now, it is for example able to read digits of pi to
      a fully accurate double. Before, the rounding error
      was large enough that precision was reduced, almost
      to single precision. But some numbers will still be
      off a little as corner cases are still not handled.
      Restrict trailing '.' written after the last digit.
      Add file.c compile-time switch GETD_ALLOW_TAIL_DOT,
      disabled by default; when disabled, changes parsing
      of numbers in SAU_File_getd() to forbid '.' without
      decimal digits after it. For use in languages where
      such a '.' needs stricter handling or preservation.
      Change log:
       * 2022-06-28: Change to improve reading precision.
       * 2022-08-27: Disable trailing dot after number by
             default, making way for possible new syntax.
    • Joel K. Pettersson's avatar
      Add debug build -? option and SAU_testopt variable. · 885c5d4c
      Joel K. Pettersson authored
      Add SAU_ADD_TESTOPT switch to 'common.h', an option
      in 'saugns.h' and 'saugns.c'.
      Meant to make it simple to pass a number via cli to
      test code in test builds.
    • Joel K. Pettersson's avatar
      Refactor durgroup timing. · 9469dc25
      Joel K. Pettersson authored
      Use new durgroup struct holding events
      as temporary allocation in parser, and
      remove the pointer in each event. Also
      merge the time_event() loop into first
      loop in time_durgroup(), looping less.
    • Joel K. Pettersson's avatar
    • Joel K. Pettersson's avatar
      Add man page. Split README. Makefile changes. · 634e39c3
      Joel K. Pettersson authored
      Add a saugns(1) man page for installation.
      Split README into README.md and doc/README.SAU,
      the latter installed under share/doc/saugns/.
      Install examples/* to share/examples/saugns,
      instead of share/saugns. (Also add a 'check'
      target, for quick verification of clean script
      parsing, i.e. simply that there's no warnings.)
      Several possibilities exist for where the
      man page should be added/removed. Do something
      very simple and hopefully sensible:
       * If "man" exists under the install/uninstall
         prefix, use it.
       * Else, go with "share/man" under the prefix.
      Some systems (e.g. OpenBSD) do not use compressed
      man pages for official packages, while others do.
      Add simple check for this less significant detail:
       * If "/usr/share/man" exists,
         compress man page if and only if
         it contains compressed man page(s).
       * Else, compress man page if and only if
         install location contains compressed man page(s).
      Change log:
       * 2019-09-07: Add a man page for installation.
             Split README into README and doc/README.SAU.
             Install examples to share/examples/saugns,
             and doc to share/doc/saugns,
             instead of examples to share/saugns.
       * 2019-09-09: Clean up man page.
             Move saugns.1 file to man/.
             Handle man dir possibilities
             more portably in Makefile.
       * 2019-09-13: Update README.
       * 2019-12-14: Handle whether or not to gzip man page
             upon install (always done before),
             according to whether the install location
             or "/usr/share/man" (takes priority if found)
             contains gzipped man pages.
       * 2019-12-21: Update 'doc/README.SAU' on "@label".
       * 2020-07-23: Update man page.
       * 2020-09-19: Update 'doc/README.SAU' on channel mixing.
       * 2021-01-22: Update man page for AUDIODEV environment.
       * 2021-11-24: Rework 'README' into 'README.md', update man.
       * 2021-11-29: Makefile: add 'make check' script -c testing.
       * 2022-02-23: Add "Contributing" to README.md.
       * 2022-07-28: Update website URLs after move.
       * 2022-08-29: Note doc licensing in & install 'README.md'.
    • Joel K. Pettersson's avatar
      Rename project to 'saugns' from 'sgensys'. · a42075bb
      Joel K. Pettersson authored
      Rename the program from 'sgensys'
      to 'saugns' (Scriptable AUdio GeNeration System).
      Change SGS prefix to SAU throughout code.
      Rename scripts from *.sgs
      to *.sau, naming the language SAU (Scriptable AUdio).
      Update descriptions in README.
      Set version to v0.3-dev.
      Change log:
       * 2018-12-05: Rename to 'saugns'. Change SGS prefix to SAG.
       * 2019-01-21: Update for newer code. Change prefix to AGS.
       * 2019-01-22: Bump copyright years. Change prefix to SAU.
             Rename scripts from *.sgs to *.sau, polish README.
       * 2019-07-04: Update for newer code. Tag "v0.3.0".
       * 2019-08-18: Increase version suffix to 'b'.
       * 2019-12-25: Update for newer code.
       * 2020-01-03: Increase version suffix to 'c'.
       * 2020-02-09: Update for newer code. Tag "v0.3.6e-2".
       * 2020-07-26: Update for newer code. Set version to v0.3-dev.
       * 2022-09-21: Update to latest code.
    • Joel K. Pettersson's avatar
      Rework '#' & 'Q' comment syntax. Reorganize scripts. · bbd209a7
      Joel K. Pettersson authored
      Language changes:
       - Change '#' line comment to '#!'.
       - Remove 'Q' (quit) keyword, re-add as '#Q'.
      Add and use '#'-override in parser. A start
      for implementing a simple preprocessor with
      '#' freed-up for further usage as a prefix.
      Update README and scripts.
      Move some more contents from devtests/,
      and prune and and clean up a little.
      Add examples/sounds/, reorganize scripts
      in examples/ a little.
      Change log:
       * 2019-08-21: Change '#'-handling, replace old 'Q'.
             Add and use SAU_File_end() for '#Q'.
             Update README and scripts.
       * 2019-08-22: Debug file module changes, tidy up.
       * 2019-08-24: Further refactor file module.
             Now use SAU_Scanner_close() for '#Q',
             as SAU_File_close() now behaves as expected.
             Set version to v0.3.2.
       * 2019-09-12: Move file module refactoring
             down to v0.2.13, with finishing touch.
             Increase version suffix to 'b'.
       * 2019-10-08: Increase version suffix to 'c'.
             (Rebased on top of new v0.2.14.)
       * 2019-11-04: Reorganize scripts.
       * 2021-07-12: Move down to new sgensys.
       * 2022-02-23: Adjust for new scripts...
    • Joel K. Pettersson's avatar
      Add '<>' placeholder syntax. Fix irregularity. · cbc3e3dc
      Joel K. Pettersson authored
      Language changes:
       * Allow use of '<>' as a generic subscope with few
         effects, similar to in older "mgensys" versions.
         Replaces the generic '[]' separate from the list
         parameters, added in v0.3.6 & removed in v0.3.8.
      This version allows the use of strings like "Osin<f>"
      for '<' around parameters, without surrounding space.
      The new '<>' syntax remains undocumented
      and is only really for testing purposes.
      Reject \num syntax when ParseLevel has a
      nest_list only. Remove now-unused parser
      flag PL_NESTED_SCOPE.
      Move setting of LATER_USED flags down to
      postparse_passes() code in a simpler way
      than in old versions (v0.3.5 to v0.3.8b)
      by adding a small SGS_ScriptOpObj object
      per op., with fields common to its refs.
      Change log:
       * 2021-11-08: Reject \num syntax based on ParseLevel
             having a nest_list only. Remove the old parser
             flag PL_NESTED_SCOPE.
       * 2021-11-09: Re-add undocumented '<>' test syntax
             as in v0.3.8 & v0.3.8b. Debug use with sub_f
             call immediately following a '<'.
         Old branch:
          - 2020-12-17: Add '<>' to replace generic '[]'.
          - 2020-12-19: Tidy changes for parser a little,
                ensure behavior the same after 12-17 change.
          - 2020-12-26: Fix scope checks after '<>'-addition.
       * 2021-11-10: Add SAU_ScriptOpObj to track last_ref
             and hold root_event and op_id. Redo moving of
             LATER_USED flags; add only that part to the
             postparse_passes() code in flattening pass.
             Move down to new sgensys.
       * 2022-02-11: Merge SCOPE_TOP into SCOPE_GROUP.
    • Joel K. Pettersson's avatar
      Partially merge script & program types, reduce duplication. · f5e312f2
      Joel K. Pettersson authored
      Allocate and use SGS_ProgramOpData for holding common
      data in SGS_Script parser output too. Rename and tidy
      SGS_Script types.
      Change log:
       * 2021-11-19: Allocate and use SGS_ProgramOpData for holding
             common data in SGS_Script parser output too. Rename and
             tidy SGS_Script types.
       * 2021-11-20: Clean up main API: Pass around script objects
             instead of program objects, use the same mempool for
             both, point to program subobjects from script objects.
       * 2022-02-03: Simplify away duplicated "op_id" field.
       * 2022-02-08: Makefile header deps.
       * 2022-09-16: Merge new script-in-program changes replacing
             the old 2021-11-20 program-in-script changes.
    • Joel K. Pettersson's avatar
      Extend num. expr. syntax with some math functions and more. · ec9355c3
      Joel K. Pettersson authored
      Add "name(value)" function evaluation syntax for numbers
      in parser. Similarly to other named things, add an array
      of names, this time in math.h, and math.c defining names
      and corresponding functions (in function pointer array).
      Add "metallic value" SGS_met() to math.h. Can be used to
      get the golden ratio number by passing 1. Supports whole
      domain of double precision values as it seems useful and
      is free.
      For now, the following function names are recognized:
       - abs(x)  Absolute value.
       - exp(x)  Base-e exponential value.
       - log(x)  Natural logarithmic value.
       - met(x)  Metallic value.
       - sqrt(x) Square root.
      (Also add the 'G' golden angle named constant for phase.)
      Numerical expressions still work the same basic way as before,
      the parser functioning as a calculator making recursive calls.
      Make parser warn on expressions that produce a NaN value
      somewhere, and not only on infinite values; matters more
      now that more things producing NaN are available. Better
      than the old behavior of silently discarding NaN result,
      after simply ignoring NaN occurring earlier.
      Change log: Main changes done by 2021-10-27.
      Phase 'G' constant and README by 2021-11-26.
      Add num_r() dangling sign check, 2022-06-07.
      Add '%' syntax and adjust '^' on 2022-06-08.
      Rebase after syntax changes move 2022-07-11.
    • Joel K. Pettersson's avatar
      Add freqamp-PM syntax. Refactor & optimize oscillator. · cd28dc58
      Joel K. Pettersson authored
      Language changes:
      * Add "p,f[...]" frequency-amplified PM modulator list syntax.
        Unlike for normal PM, the modulation index (amplitudes) are
        multiplied by the carrier frequency, scaled down so ~632 Hz
        gives normal amplitude.
      Refactor oscillator, split "phasor" type with new
      buffer-filling function, make the main run functions
      use passed pre-filled integer phase increase and offset
      buffers, instead of buffers for frequency and phase offset
      in floating-point. The splitting of the processing loop turns
      out to increase performance signficantly, in additon.
      Add ~632 Hz constant to math.h, used as a sensible
      middle-point in the frequency range (the geometric
      mean of 20 and 20000, common for audio equipment.)
      Change log:
       * 2022-02-20: Implement "p+f[]" syntax, refactor.
       * 2022-02-21: Update documentation.
       * 2022-02-22: Tweak scripts & use the new syntax:
             'examples/tests/vibrato-pm.sgs'  (new file)
       * 2022-02-23: Change naming in the documentation.
             (frequency-multiplied -> frequency-linked.)
             Adjust -p printout, use 3-letter mod abbrs.
       * 2022-06-14: Rename 'phasor' to 'freqor'  (as it
             provides non-integrated values). Remove env
             version of oscillator code, split out mixer
             functions for buffer handling including amp
             and use in generator.c - same output/result
             and also tests faster on my x86-64 laptops.
       * 2022-06-15: Simplify new generator.c code more.
       * 2022-07-11: Merge new syntax changes, fPM usage
             adjusted to "p,f[]" matching later version.
       * 2022-08-24: Simplify the oscillator more making
             a plain phasor out of the freqor. Removes a
             buffer from the generator code, works well.
             Set oscillator phase as uint32_t in parser.
    • Joel K. Pettersson's avatar
      Refactor parser more & fix edge case. Revise mempool again. · 48a71dd6
      Joel K. Pettersson authored
      Parser refactoring:
       * Make parser produce a linked list of modulator sublists
         per parent node. Simple and more generic than using one
         pointer per type of modulator list.
      This fixes the test case of "devtests/ref-unused_node.sgs"
      where referring back to an orphaned node in a script makes
      the reference touch and modify the wrong node (because the
      orphaned node hadn't had its ID properly set). Previously,
      this was fixed by a larger change splitting the post-parse
      processing stage, but the modulator list change is enough.
      Except for a small performance boost, the mempool has been
      much the same since 2014, until now. Change to use dynamic
      sizing of memory blocks, double the size after every power
      of two block count reached. Use 512 as default start size.
      Performance seems basically unchanged running my old test.
      (Changes probably cancelled out as fewer blocks are made.)
      Change log:
       * 2021-01-10: Flatten types in mempool. Refactor to place
             new allocation pointer array for freeing separately
             and change sizing per block, inceasing it once each
             new power of two number of blocks has been reached.
       * 2021-01-12: Tweak mempool. Adjust mempool heuristic for
             skipping fully-used blocks to increase threshold if
             proportion below 2/3 of blocks and increase default
             block start size from 128 to 512. Simplify away the
             extra pointer per block and separate array, growing
             allocations downward instead.
       * 2021-07-12: Move down to new sgensys.
       * 2021-07-23: Tidy parser code a bit more. Make modulator
             lists from parser a list of sublists; shorter code.
             Move down "devtests/ref-unused_node.sgs" test case.
         Old branch:
          - 2019-12-22: Add 'devtests/ref-unused_node.sau'.
       * 2021-07-24: Tidy parser yet more.
    • Joel K. Pettersson's avatar
      Change ramp params & time logic for ease of use. · 55ca293d
      Joel K. Pettersson authored
      Language changes:
       * Ramp '{}' subparameters:
         - Rename 'v' to 'g' (goal), and 'c' to 'r' (ramp).
         - Add 'v' (start value), as alias for the ordinary
           value before the '{}'; allow use of one of them.
       * Fix and tweak default time behavior, more remains.
       * Rename ramp 'cos' to 'sin' (sinuous curve). It's
         maybe more intuitive, and seems less unexpected.
      Rework the ramp module and parser, to fully support
      incremental updates to the ramp subparameters. Each
      named parameter now has at least one flag, to track
      what's new, with extended SGS_Ramp_copy() handling.
      Timing logic is also extended to track and decrease
      time when goal isn't enabled too, for a new default
      for ramp "t" of the remaining time when set before,
      until the old remaining time which was set expires.
      Refactor ramp, extending the struct and simplifying
      the use of the functions. Now SGS_Ramp_copy() fully
      handles updates for each ramp in generator.c. Break
      out SGS_Ramp_get(), may possibly have further uses.
      Fix ramp behavior when abandoning old goal.
      When one goal replaces another, unfinished,
      set the next value from the old as the used
      new start value. Previously after a shorter
      time than the ramp time, changing ramp goal
      would awkwardly keep the old start value, a
      sudden jump back to it resulting.
      Make ramp 'sin' fill shape more accurate.
      Use a degree 5 polynomial for 'sin' ramp,
      a step up from the previous (smoothstep).
      Accurate enough that use in an oscillator
      would only add a 5th harmonic at ~-84 dB,
      it's been shifted to the ramp range used.
      Generally grow outer time default from inner time;
      document in the README and make it work generally.
      Some bugs and quirks related to compound steps and
      also reported -p duration remain for this, though.
      Fix too long -p duration for some scripts with new
      flag check in parser. This is a hacky solution, an
      overhaul with new node time organization is needed
      to fix all small remaining bugs and irregularities
      in the use of a post-parse timing adjustment pass.
      Add the simple 'examples/tests/long/sin_pm_1m.sgs'
      (using the new default time behavior for brevity).
      Change log:
       * 2021-06-19: Change ramp to make pos a field.
       * 2021-11-25: Dynamically allocate SGS_Ramp
             instances held by script/program types.
       * 2021-11-29: Rename ramp 'c' to 's', 'v' to 'g'.
       * 2022-05-19: Rename ramp 's' to 'f'.
             Rename ramp fill type 'cos' to 'sin'.
       * 2022-05-21: Change ramp 'f' to 'r', 'g' to 'v'.
       * 2022-06-02: Make ramp 'sin' shape more accurate.
       * 2022-06-06: Rename ramp 'v' to 'g'.
       * 2022-06-09: Fix too long -p duration for some scripts.
       * 2022-06-13: On outer default time from inner duration,
             document in README.SAU and make it work generally.
             Some bugs and quirks related to compound steps and
             also reported -p duration remain for this, though.
             Make ramp default times update on changed default.
             Add the simple 'examples/tests/long/sin_pm_1m.sau'
             (using the new default time behavior for brevity).
       * 2022-07-08: Fix ramp behavior when old goal,
             not expired, is replaced by a new.
       * 2022-07-09: Allow ramp '{}' after the state,
             not only alone. (Rebased down 2022-07-11.)
             Ramp changes for more flexible subparams.
       * 2022-07-13: Add ramp 'v' subparameter as alias
             for state value.
       * 2022-07-30: Make 'r' default the previous value.
       * 2022-09-19: Move down to sgensys.
    • Joel K. Pettersson's avatar
      Simplify parser node lists and rework memory handling. · 85bc08c7
      Joel K. Pettersson authored
      Remove the ptrarr module use in parser, and simply use
      the linked list node structure for everything, with an
      extension. Use mempool for the allocations. This means
      no memory leaks even though e.g. adding and clearing a
      list of operators in the same event leaves allocations
      unused/dangling for those operators for the most part.
      Move creation of mempool for postparse conversion into
      the parser, so that more long-lived data can be shared
      and allocated by the parser. Adjust parseconv, a parse
      (script type specific data) now optionally kept after.
      Change log:
       * 2021-07-17: New simpler work to use linked node lists from
             parser. Redone for "older" sgensys.
       * 2021-07-18: Debug and re-tidy, matching earlier clean-ups.
       * 2021-12-23: Merge changes to allocate and use
             temporary event branch structs. Add & use temporary
             mempool for allocations not kept in final output.
       * 2022-09-16: Adjust script.h & program.h types further,
             the parser creating the main mempool for the latter
             and the "program" optionally preserving the "script".
       * 2022-09-17: For consistency (easily adjusted) keep the
             symtab until discarding the script struct.
    • Joel K. Pettersson's avatar
      Change panning/channel mixing syntax. Tidy & fix in parser. · 951ac351
      Joel K. Pettersson authored
      Language changes:
       * Replace panning 'P' keyword with channel mixing parameter
         'c' and 'S c' for default. The scale changes from 0.0-1.0
         left-right to (-1.0) left, 0.0 center, 1.0 right. And the
         letters 'C', 'L', and 'R' become named constants for 0.0,
         (-1.0), and 1.0.
      The panning or "channel mixing syntax" is now the same as in
      the 2020-06 "mgensys" version, replacing the 'P' (2011-12-13)
      syntax and earlier 'b' (2011-04-10) variant.
      Adjust SGS_Scanner_getd() to call a callback if provided for
      named constant reading, using this both for the new channel
      C/L/R constants and the old note syntax code after conversion.
      Simplify down voice handling to fix the semantics.
      Move pan fields from voice/event nodes to op data nodes
      (before the generator's own types). In parser, only add
      one carrier per event. The changes combine for removing
      the quirk giving several operators on the same line the
      same value, if in one go (setting it for one setting it
      for all). Thus, now it works like in 2020-06 "mgensys".
      Remove voice parameters, except in program.h types, where
      SGS_PVOP_GRAPH is left for possible further uses for now.
      There's more room to simplify code, and this may simplify
      changing the flatter sgensys design.
      Re-enable disabled call in parser to
      split an op. event after time shift.
      Update README.
      Change log:
       * 2020-09-19: Add callback to SAU_Scanner_getd()
             for reading of named constants.
             Port 2020-06 "mgensys" channel mixing syntax.
             Move devtests/panning.sau to examples/tests/.
             Update README.
       * 2020-09-21: Tidy up changed scanner code.
             Add handling for sign before named constant.
             (Redone for consistency, not currently used.)
       * 2020-10-03: Make scanner always call numconst_f when given,
             simply check return length. Remove useless warning when
             note syntax callback called for non-note characters.
       * 2021-07-10: Move down to after scanner clean-up.
       * 2021-11-26: Clarify 'c' is for non-nested ops in README.
       * 2022-02-23: Merge change for semantics.
             Also, re-enable '/' step-splitting.
         Old branch:
          - Change log: 2021-06-19, saugns draft
            backported, 2021-07-10, for sgensys.
            Also bring over a small refactoring.
            More tweaks 2021-07-23, tidier code.
            Default 'c' 2021-11-26 timing fixed.
    • Joel K. Pettersson's avatar
      Rework scanner, clean up more in parser. · 4ec1c74a
      Joel K. Pettersson authored
      Redesign scanner, and use the new way of
      filtering whitespace in parser. Further
      testing of line and char position numbering
      needed, but now better than with the v0.3.0
      scanner design. (Handling of warnings needs
      a more convenient way to specify the correct
      character position per warning.)
       * Add whitespace filtering level setting.
         Setting the level replaces the whitespace filtering
         functions in the table for the scanner instance.
       * Remove "nospace" versions of get/try functions.
         Simplify get function. Remove old space-skipping
         inline functions.
       * Fix as-yet unused ability to unget and re-get
         multiple characters in a row, with filtering of
         whitespace, etc., intact.
      Further clean up in parser:
       * Clean up ParseLevel pointer usage. Pass around pointers
         to the main parser struct instead.
       * Simplify away the 'location' enum and DEFERRED_* flags,
         use one flag, one pointer instead.
       * Add slightly nicer generic warning messages for invalid
         characters in the main read loops.
      Change log:
       * 2019-07-07: scanner: Add ws filter level setting.
             Remove nospace versions of functions.
             Use next design. Consistent for filtering,
             even if changed. Clear up ws types naming,
             really fill in everything. Tidying.
       * 2019-07-09: Scanner flag fix.
             (Recommitted after fixing the fix.)
             Set version to v0.3.1.
       * 2019-07-11: Microflensing.
             scanner: Remove "RAW" (NULL-pointer) ws level,
             rename "PASS" to "ALL" and make it the default
             (instead of "RED1").
       * 2019-08-05: Place after new v0.3.0,
             with July syntax changes split out into v0.2.13.
       * 2019-08-17: Remove scanner ws levels between ALL and NONE.
             (Not needed in current program.)
       * 2019-10-31: (Rebased on top of new v0.2.15.)
       * 2019-12-24: Merge ramp and v0.2.5-related changes.
       * 2020-02-09: Refactor num.exp. parsing.
       * 2021-07-10: Move down redesign changes
             to after change to use the scanner
             and merge with symtab refactoring.
             Keep version at v0.2-dev.
       * 2021-07-24: Move down a little parser style changes.
       * 2022-02-02: Move down further parser tidying:
         Old branch:
          - 2020-12-17: Simplify away the old "location" values,
                use a function pointer combining their role with
                the now-removed DEFERRED_* flags.
          - 2021-06-19: Tidy up parser function parameter use of
          - 2021-11-09: Fix for later-tested case for sub_f call.
                (Check for deferred call before, not after, cases
                handling for current character to fix recursion.)
       * 2022-06-07: Fix remaining bug in this version.
             Correct scanner multiple character ungets,
             while not (yet) actually relied upon; used
             to produce broken results when re-getting.
             Also improve / expand `test-scan` code, to
             finally cover the get & unget combination.
       * 2022-08-24: parser: Add slightly nicer generic warnings.
    • Joel K. Pettersson's avatar
      Use the new scanner. Extend comment syntax. Clean-up. · d8f4f65a
      Joel K. Pettersson authored
      Make the test scanner functional for use in the parser
      and change the parser to use the scanner module.
      (The scanner is now also used in the test lexer,
      replacing much of it.)
      C-style and C++-style comments are now supported
      (in addition to '#' line comments and the use of 'Q').
      The parser's old PScanner and warning printouts are
      replaced. Warnings now provide not only line, but also
      character, numbering. Most direct use of the file module
      is replaced. String and number reading is also further
      Scanner design changes include:
       * Flesh out design for tracking line and character positions.
         A fixed number of multiple ungets in a row are supported,
         using a circular buffer for scan frames, advanced each get.
       * Add pointer parameter to warning/error message functions
         for optionally overriding position info. (E.g. copy earlier
         position, use it when warning after more scan calls.)
       * Add number-reading functions (wrappers around those of
         the file module).
       * Add further space-skipping reading functions.
      Further refactoring:
       * Always check for NULL pointer in type
         destroy_*() functions, remove checks where called.
       * Minor code style changes for consistency.
      Set version to v0.2-dev.
      Reindent parser.c (the only remaining file).
      Use new comment styles in scripts.
      Change log:
       * 2019-05-15: Use the new scanner.
             Initial merge after changes as of v0.4.4.
             Adapt: Preserve use of symtab in scanner,
             remove wrapper function around string reading
             in parser. Let scanner handle file opening,
             replacing v0.4.1 additions in builder.c.
             Some comment and code clean-ups.
         Old branch:
          - 2018-12-17: scanner: Some renaming and clean-ups.
                Add, use, flag for overwriting scan frame next get.
          - 2018-12-18: scanner: Add advance_frame(), used to
                handle scan frames for symbol string reading.
          - 2018-12-19: Use scanner module in parser.
                Add SGS_Scanner_geti(), SGS_Scanner_getd().
                Debug line and char numbering.
                Move symtab use from scanner to parser,
                move string buffer from scanner to parser,
                refactor string reading in parser.
                Rename SGS_Scanner_unget()
                back to SGS_Scanner_ungetc().
                Add quick handling for unfiltered characters
                to SGS_Scanner_tryc() and SGS_Scanner_tryc_nospace().
                Move reading of SGS_SCAN_C_LNBRK
                flag out from SGS_Scanner_tryc_nospace().
                Add scanner statistics printing #define
                to common.h and #if'd counters in scanner.c.
                Refactor parser time number scanning.
                Further clean-ups in parser.
          - 2018-12-21: Comment and other minor clean-ups.
                Update README.
          - 2019-01-05: Complete branch merging.
                Use SGS_Scanner_getc_nospace() in parser.
                Clean up printing of no label warning in parser,
                silencing warning about non-const format string.
                Refactor parser uses of scan_symafind(),
                moving warning printouts into it.
          - 2019-01-09: Use scanner in lexer.
                Add SGS_SCAN_S_QUIET flag, use in lexer
                for SGS_LEXER_QUIET compile-time mode.
                Note: File module needs design change
                for safe unget, crash preventing code
                added to scanner in the meantime.
                Complete branch merging.
          - 2019-01-10: Complete branch merging.
                Remove obsolete debug code in scanner
                (file module now fixed).
          - 2019-01-11: Set version to v0.6.0.
                Clean-up in lexer. Use SGS_Scanner_getc_nospace().
          - 2019-01-15: Restructure parser code to
                reduce differences with previous version.
                No functional change.
       * 2019-05-17: Some tidying for last branch merge.
       * 2019-05-19: parser: Avoid duplicating code for name of
             script for string as file, copy name from file object.
       * 2019-05-24: Set version to v0.5.1.
             scanner: Name changes.
             in general: Always check for NULL pointer in type
             destroy_*() functions, remove checks where called.
             Minor code style changes for consistency.
       * 2019-05-28: Merge refactoring.
             Reindent parser.c (and adjust comments).
         Old branch:
          - 2019-02-08: Refactor parser warnings for
                EOF before closing character, and closing
                character without opening character.
       * 2019-06-04: Move refactoring back to v0.5.1,
             use old version number.
       * 2019-06-05: Merge parser diff after v0.2.3 syntax change.
       * 2019-06-07: Update debug script for too-long label
             for new scanner (new max length is 255).
       * 2019-06-13: Set version to v0.3.1.
       * 2019-06-16: Adjust parser for new v0.2.4 syntax changes.
       * 2019-06-20: Set version to v0.3.0.
       * 2019-06-30: Place after the split-out v0.2.12.
             Update comment style used in scripts.
       * 2019-07-04: Update for v0.2.12 'r' syntax change.
       * 2019-08-05: Update for v0.2.13 syntax changes.
       * 2019-10-08: Place after new v0.2.14.
       * 2019-10-31: Place after new v0.2.15.
       * 2019-12-21: Merge 'S a' multiplier apply-to-ramp fix.
       * 2019-12-22: Merge compound step timing fix.
       * 2019-12-24: Merge changes related to v0.2.5 & v0.2.13.
       * 2019-12-25: Merge ramp default time changes.
       * 2020-02-09: Merge num.exp. fix for successive subtractions.
       * 2020-07-23: Merge renaming in ramp module.
       * 2020-07-26: Set version to v0.2-dev.
       * 2021-07-10: Move down as in v0.3.3
             and merge new work before the skipped.
             (Fixes included, not the stage split.)
       * 2022-02-02: Merge changes for symtab update.
       * 2022-07-12: Merge changes for syntax handling,
             fix num_r() -- it wrongly ignored whitespace
             in this version.
       * 2022-08-11: Merge numerical variables feature,
             fix ramp time value reading in this version.
    • Joel K. Pettersson's avatar
      Add ',w' ramps, improve performance. Add scripts. · b0977977
      Joel K. Pettersson authored
      Syntax changes:
       * Allow value ramp values for the second frequency and
         amplitude. Make the syntax consistent in this regard.
      Add position-updating skip function for ramp,
      similar to run function except there's no output.
      Use to update second freq and amp ramps in generator
      without generating samples when no FM or AM is done.
      This resolved the "todo" regarding dynfreq/dynamp
      ratio flags.
       * Change ramp code to improve performance.
       * Always handle/allow NULL mulbuf in ramp.
       * Further accept a NULL pos to skip ahead,
         making the target value the state value.
      Update scripts and README.
      (On amplitude modulation, describe ring modulation,
      which is also supported since early 2011 versions.)
      Add 'examples/tests/long/sqr_am_2m.sgs',
      under new dir for long duration scripts.
      Add 'examples/tests/ixa_synth_vs_pm.sgs'
      (recreates IXA synthesis result using PM
      & RM with a triangle, sine, and square).
      Change log:
       * 2019-08-04: Set version to v0.2.13.
             Move syntax changes and parser fixes
             down from v0.3.1:
         Old branch:
          - 2019-07-18: Change AM & FM syntax.
                Make 'p' more permissive for consistency.
          - 2019-07-20: Use ramps for second freq, amp.
                TODO: Fill in the missing pieces in
                generator for fully consistent handling.
          - 2019-07-21: Simplify addition in generator.
                Remove incomplete and unneeded extra code.
                Clarify remaining added TODOs.
          - 2019-07-30: Add SAU_Ramp_skip(), use in generator.
                Remove now-resolved new TODOs.
       * 2019-08-06: parser: Add missing lines to backport
             (matching commits for later versions),
             v0.2.13 now functions as expected.
       * 2019-08-07: Move 08-06 Makefile -ffast-math portability fix
             to v0.2.3 and v0.2.4.
       * 2019-12-21: Merge 'S a' multiplier apply-to-ramp fix.
       * 2019-12-22: Fix missing default time adjustment
             for amp2 and freq2 ramps. Adjust details to
             avoid inf. time.
       * 2019-12-25: Merge clean-up and ramp changes as of 12-25.
         Old branch:
          - 2019-12-24: Move down clean-up change from v0.3.3b.
                Merge ramp default time changes.
       * 2020-01-03: Fix generator crash due to
             not counting FREQ2 and AMP2 values
             correctly, by merging the cleanup. (Remove counting.)
       * 2020-07-23: Merge renaming in ramp module.
       * 2020-07-26: Keep version at v0.2-beta.
             Change ramp module to ISC license, clean up comments.
         Old branch:
          - 2019-08-16: Re-order ramp run & skip function params.
       * 2020-10-27: Make ramp SSG_Ramp_skip()
             skip all remaining values if pos is NULL.
             May remain unused without a new use-idea.
       * 2021-01-12: ramp: Move mulbuf use into fill functions,
             improving the performance with clang 10. Add NULL checks
             in SSG_Ramp_run() to allow future calls with no mulbuf.
       * 2021-01-15: Add noinline attribute for SSG_Ramp_fill_hold(),
             document necessity with clang where inlining hurt x86
             performance (costing half the 10% speed-up on the laptop
             with i386 OpenBSD, fixed with the use of SSG__noinline).
       * 2021-01-16: Tidy ramp.c and correct the comment on clang.
       * 2021-06-18: Add 'sqr_am_2m.sgs' script (from 2021-01-14)
             under new dir examples/tests/long/ for long duration.
       * 2021-07-09: Merge osc changes. Tweak new script for phase
             differences (or roughly, by ear-taste) in new osc.
       * 2021-07-19: Tweak test script after 'sqr' phase fixed.
       * 2021-09-03: Add 'examples/tests/ixa_synth_vs_pm.sgs'.
       * 2022-08-24: Merge further README changes with
             the syntax changes now moved down further.
         Old branch:
          - 2021-09-10: Correct and expand README
                on amplitude modulation. Describe ring modulation
                which is also supported since early 2011 versions.
          - 2022-02-21: Clarify how 'r' works differently for FM
                modulators than for other modulators (the old and
                still-used 2011 behavior).
          - 2022-07-11: Merge changes which obsolete the increased
                permissiveness part of the syntax handling changes.
          - 2022-07-12: Backport simple change for AM & FM syntax,
                use ",w" instead of "," and remove "~". Edit README.
  2. 22 Sep, 2022 8 commits
    • Joel K. Pettersson's avatar
      Tweak timing modifier syntax, replace 's'. Refactor timing. · 7a56de86
      Joel K. Pettersson authored
      Rework timing syntax.
      Language changes:
       * Make '|' reset delay for next step to duration of prior ones
         rather than add it to delay from other modifiers before '|'.
       * Rename timing modifier '\' to '/',
         (reverses change from 2011-07-01).
       * Remove special 't'-literal "/t" value (unused 2011 feature).
       * Remove O 's' silence parameter (adding initial silent time);
         replaced by new '\' subshift feature.
       * Add new timing modifier '\' subshift syntax. Only applies
         to a current event, splitting it and delaying the later part
         similarly to a ';' compound step (and combinable with ';'
         for e.g. silent gaps, made easy with default time handling).
      Rework related text in README.
      Delete "silence" feature from generator; using the '\'
      subshift gives the same result (as long as the '\' is
      placed prior to updated parameter values in scripts).
      The new version with adjusted scripts creates a byte-
      for-byte identical audio output.
      Design notes:
       * Initially, the new '\' syntax makes use of compound step
         logic with a flag for marking if a node was split to add
         subshift wait, to distinguish how to handle a sub-event.
       * Before a first, mostly working version, testing nesting
         of compound step sub-lists was done; each ';' sequence
         sub-list could contain nested '\' sequence sub-lists,
         a new event sequence struct holding every event list.
         - That extension of the old mechanism of time_event(),
           flatten_events(), etc. does work. It handles nesting,
           but there was no point, as it complicated the problem.
         - Such nesting could be a good idea for other new syntax.
       * Event duration is now pre-calculated in timing code after
         the parser, and tied to sub-events, while operator times
         are now allowed to be shorter. Moves carrier time count
         code piece for voice allocation back out of parseconv.
       * Finally, timing in the program no longer depends on
         the old structure of the generator. The removal
         of the silence code makes redesign simpler.
      A usable version done by 2021-12-27.
      Backported to sgensys on 2022-01-10.
      Rewrote README. Adjusted semantics 2022-02-15.
      Fixed bugs ('defaulttime3.sgs') on 2022-06-07.
    • Joel K. Pettersson's avatar
      Tweak and fix oscillator behavior and anti-alias PM. · f1ea71c6
      Joel K. Pettersson authored
      Tweak code to restore features like non-zero output for
      0 Hz (or no phase increment), needed to allow DC output
      and for PM driving 0 Hz oscillator to give a waveshape.
      Tune start values to get non-zero output for PILUT use,
      on starting when it's expected. Apply anti-aliasing for
      PM, by no longer moving both diff'd values each sample.
      Use doubles for intermediate values, including wave lerp,
      solving the earlier problem with occasional overshooting,
      where factoring PM into differentiation made rare samples
      abnormally large, apparently due to inadequate precision.
      Do oscillator phase increment pre- rather than post-sample;
      otherwise samples appear off-by-one delayed with PILUT osc.
      (Fix bug added in v0.3.9 producing distorted
      audio when PM is used with large amplitudes.
      The alias-suppressing oscillator implemented
      required better-than-linear interpolation to
      avoid producing jagged, bitcrush-ish result.
      Improve LUT interpolation; use Hermite for 4
      values (3rd degree). Formula taken from Olli
      Niemitalo's Polynomial Interpolators paper.)
      Change log:
       * 2021-07-06: First version. Use simpler oscillator
             code for 'sin'. Add USE_NAIVE testing define.
       * 2021-07-08: Use oscillator differentiation for PM
             too. Also use the new code for sine waves. To
             solve the problem with occasional overshoots,
             use double as needed for intermediate values.
       * 2021-07-19: Refactor extra values for wave types,
             store one array of a struct with them instead
             of one array per value. Add phase shift value
             and use instead of extending LUTs for shifted
       * 2021-07-20: Increment oscillator phase before using it.
             Un-delays oscillator output by one sample,
             and removes unit delay from the use of the
             frequency buffer. Fits newer phase-setting
             for best accuracy, but at ~10% speed cost.
       * 2021-07-26: Put #define USE_PILUT in osc.h.
       * 2022-02-23: Fix bad distortion with large PM amplitudes.
             Use Hermite interpolation to avoid jagged waveshape.
    • Joel K. Pettersson's avatar
      Redo wave type anti-aliasing using pre-integration. · 6019d5b8
      Joel K. Pettersson authored
      Remove the 2019 LUT 'sqr' and 'saw' step rounding
      which was fixed, not adapted to the frequency, to
      start over with earlier naive wave shape LUTs.
      Use pre-integration to provide some anti-aliasing
      for wave types instead, extending the oscillator.
      Only first-order for now, all wave types provided
      with a new set of pre-integrated LUTs ("PILUTs"),
      and scaling and offset values to use them the way
      the old were. The old LUTs and code also remain.
      This improves quality for all aliased wave types,
      similarly to how the DPW (differentiated parabolic
      wave) trick affects sawtooth waves. Computational
      overhead is fairly small. Note that PM is applied
      outside the smoothing to avoid rare large values.
      * Change SGS_Wave_luts array to pointer array.
      * Refactor osc, move LUT selection into SGS_Osc_run*().
      * Extend sin LUT by placing -cosin quarter
        first, for use as 'sin' PILUT.
      * Ensure osc module allows clickless differentiation
        start when LUT and/or phase are (re)set.
      * Rip out old 'sqr' and 'saw' LUT shape rounding.
      * Extend tri LUT by placing phase-shifted
        "-cotri" first, for use as 'sqr' PILUT.
      * Parabolic wave in 'saw' PILUT for DPW-like result.
      * Extend SGS_Wave_print() code used while testing LUTs.
      * Add 'tri' PILUT.
      * Tweak 'saw' LUT.
      * Use new fill function for PILUTs to calculate the messier-
        looking 'ahs', 'hrs', 'srs', and 'ssr' ones from the LUTs.
      Inspired by T.Rochebois's article, "Anti Aliasing Oscillators
      and Distortions with Pre Integrated Wave Tables".
      Change log:
       * 2021-07-03: First version.
       * 2021-07-19: Correct 'sqr'; extend tri LUT, like sin,
             for the correct phase.
    • Joel K. Pettersson's avatar
      Refactor parseconv, program.h types, and more. · 7e610db1
      Joel K. Pettersson authored
      Refactor parseconv, use mempool for all produced data.
      Rename ptrlist to ptrarr.
      Add and use "mpmemdup" methods for arrtype and ptrarr,
      replacing ordinary "memdup" and traversal for freeing.
      Removes the SGS_POPP_ADJCS flag and parameter. Replace
      the adjcs field and structure with one field for every
      modulator type, using the same type for carriers. Tidy
      up handling in parseconv a bit. Increases pointers, by
      a few, but otherwise tidies up a bit in generator too.
      Change log:
       * 2020-10-08: Simplified reworking of part of v0.3.6 redesign.
             The old ptrlist module is used, and nodelist is skipped.
         Old branch:
          - 2019-12-31: Renaming and refactoring.
                Add and use arrtype "mpmemdup" for scriptconv
                and voicegraph arrays, removing all but one free.
          - 2020-01-01: Add and use ptrlist "mpmemdup"; simplify,
                turn SAU_ProgramEvent array into array of pointers.
          - 2020-01-03: Merge de-const-ify ptrlist void pointers.
          - 2020-01-04: Move down from later v0.3.6 commits.
          - 2020-02-27: Remove const from parameters for arrtype
                memdup functions.
          - 2020-07-26: ISC-relicense arrtype, ptrlist, nodelist.
       * 2020-10-09: Move down to sgensys v0.2-beta.
       * 2021-11-02: Move to saugns on top of new sgensys.
         Old branch:
          - 2020-10-09: Rename ptrlist to ptrarr.
       * 2021-11-19: ptrarr: Allow setting count to zero
             as a soft clearing (just like arrtype is used).
             Note that it's mutually exclusive with soft copying.
       * 2022-01-30: Backport to older sgensys, as part of
             new redesign work. Adjust changes to split it
             back before more needs to change in parser.
         Old branch:
          - 2019-12-26: Remove SAU_POPP_ADJCS flag,
                replace checks using other information.
                Replace SAU_ProgramOpGraph and SAU_ProgramOpAdjcs
                types with SAU_ProgramOpList, simplify code.
          - 2020-10-07: Merge with changes from after new node list
                code was added & used, preserving old ptrlist usage.
          - 2021-07-18: Add 2020-12-04 devtests/pm-addremaddrem.sgs.
       * 2022-07-29: Make arrtype allow pre-setting asize for larger
             initial allocation. Remove public SGS_ArrType_upsize().
    • Joel K. Pettersson's avatar
      Basic ramp curve changes. Refactor more. Add scripts. · 0928c867
      Joel K. Pettersson authored
      Ramp curve changes:
       * Rename the old 'exp' and 'log'
         to 'xpe' (exponential envelope) and
         to 'lge' (logarithmic envelope),
         respectively. (The 'xpe' type is the most
         natural-sounding for envelope-like uses.)
       * Add new 'exp' and 'log' which internally
         select one of 'xpe' or 'lge' depending on whether
         the curve rises or falls, in order to behave much
         more like people would expect
         from curves named 'exp' and 'log'.
       * Add 'cos' curve, which rises or falls like a cosine
         moves from bottom to top or top to bottom. (Rougher
         approximation than would be used for an oscillator,
         but 99% accuracy seems good enough for ramp curve.)
      Update scripts and README for changes,
      add "engine_rumble.sgs"
      and "hearingrange.sgs" (sweep from 20 Hz to 20 kHz), and
      move devtests/drum.sgs to examples/unnamed3.sgs.
      Refactoring changes:
       * Further refactoring of the file module, part 2.
      Reindent generator.c.
      Change log:
       * 2019-05-28: Reindent generator.c.
       * 2019-06-30: Merge down slope->ramp and curve changes,
             along with script updates.
             Set version to v0.2.12.
         Old branch:
          - 2019-06-22: Begin v0.3.1-beta.
          - 2019-06-27: Rename 'exp'/'log' slope types
                to 'esd'/'lsd', add new 'exp'/'log' types which
                select 'esd' or 'lsd' for increase/decrease.
                Update scripts for changes, add "engine_rumble.sau",
                move devtests/drum.sau to examples/unnamed3.sau, and
                add "freqrange.sau" (sweep from 20 Hz to 20 kHz).
          - 2019-06-28: Change "slope change type" to "curve type"
                in script naming and parser, for consistency.
                Set version to v0.3.1. Update comments in slope.c.
                Rename "freqrange.sau" to "hearingrange.sau".
          - 2019-06-30: Rename slope module to ramp.
       * 2019-08-07: Merge Makefile -ffast-math portability fix.
       * 2019-12-12: Fix indentation in generator.c.
       * 2019-12-25: Merge ramp default time changes.
       * 2020-01-03: Merge clean-up changes.
       * 2020-07-23: Merge ramp & generator changes.
       * 2020-07-26: Keep version at v0.2-beta.
       * 2020-08-21: Split out this commit from 'r' syntax
             changes and more (which used to be above).
       * 2021-06-27: Rename ramp 'esd' to 'xpe', 'lsd' to 'lge'.
       * 2021-09-07: Add 'cos' ramp curve.
       * 2022-01-10: Move down file module changes.
         Old branch:
          - 2019-09-12: Merge down 08-24 file module refactoring,
                with finishing touch.
          - 2020-01-03: Merge -pedantic change for file.c.
          - 2020-07-23: Change file module to ISC license.
       * 2022-02-03: Move down related refactoring.
         Old branch:
          - 2020-08-25: Add, use parameter flag masks.
          - 2020-09-18: Rebase, tweak previous change.
       * 2022-07-16: Undo splitting of mixer module.
         Old branch:
          - 2019-05-28: Reindent generator.c.
          - 2019-06-13: Split out mixer module from generator.c.
          - 2019-06-16: Merge back refactoring,
                keep old buf size in generator.
          - 2019-06-18: Update generator buf size to
                match new older version.
    • Joel K. Pettersson's avatar
      Rework audio mixing. Refactor generator. Change wave types. · ed45dfb0
      Joel K. Pettersson authored
      Use floating-point processing in generator
      internally, until writing 16-bit output,
      instead of mixing float and int buffers.
      For PM phase offsets, get 32-bit int values
      from float buffer, instead of 16-bit values.
      Rework mixing, add clipping for audio output.
      Move oscillator sample block fill code
      to osc.c (from generator.c). Move lut,
      coeff fields to SGS_Osc type, from the
      types in generator.c.
      Change wave types:
       * Rename wave type:
          - 'sha' -> 'ahs' (absolute half-frequency sine).
          - 'szh' -> 'hrs' (half-rectified sine).
          - 'ssr' -> 'srs' (square root of sine).
       * Add new wave type:
          - 'ssr' (squared & square root of sine).
      Change log:
       * 2018-11-09: Complete changing generator to use float
             internally. Rework mixing, clip output.
             Move script.h and ptrlist to builder/.
             Complete branch merging.
       * 2018-11-11: Minor refactoring in generator.
             Minor comment clean-up.
       * 2019-05-28: Merge refactoring.
         Old branch:
          - 2019-02-07: Move osc block running to osc.c
                (split from generator.c).
       * 2019-06-16: Merge bugfix for generator timing,
             for newer adjusted design.
       * 2020-07-23: Split out after ramp and other refactoring.
             Merge renaming in ramp module.
             Replace osc module with newer version
             from the 2020-06 "mgensys" experiment,
             refactoring generator for moving coeff
             and lut fields to SGS_Osc. Now wave is
             ISC-licensed, along with the new osc.
       * 2020-07-26: Keep version at v0.2-beta.
       * 2021-06-27: Rename wave type 'ssr' -> 'srm',
             add new 'ssr'.
       * 2021-06-28: Rename wave type 'sha' -> 'ahs',
             and 'szh' -> 'hrs'.
       * 2021-06-29: Rename wave type 'srm' -> 'srs'.
    • Joel K. Pettersson's avatar
      Rework ramp module. Refactor uses and more. · 288571fe
      Joel K. Pettersson authored
      Refactor ramp parameters and their uses:
       * Remove the old SGS_Ramp type,
         renaming the SGS_RampParam type to SGS_Ramp.
       * Separate the ramp fill functions from the
         type and its uses. (E.g. future envelope support
         could use the fill functions with a different
         data structure and surrounding logic.)
       * New SGS_Ramp_run() function fully replaces
         parameter running function in generator.c.
       * Remove voice & operator attr fields and flags;
         these are now fully replaced by the SGS_Ramp
         flags and code.
       * Cleaner code for handling ramp data in parser
         and generator.
      Todo: Since earlier, dynfreq/dynamp parameter
      ratio flags are ignored; to correct handling.
      For now, they are simply removed.
      Improve -p printout, extending info for 'f' parameter
      and adding it for 'a' on each main per-operator line.
      Also refactor more modules:
       * Modularize parseconv a bit, while keeping voice graph
         traversal in the same file until scope or use change.
       * Further refactoring of the file module, part 1.
       * Make arrtype add method return pointer to item
         in current array allocation, for initialization.
         Rename arrtype SGS_UInt8Arr to SGS_ByteArr.
      Change log:
       * 2018-11-08: Move wave module to program/.
             (Changes for mempool, moved to earlier commit.)
             Fix Makefile.
       * 2019-01-14: Complete branch merging.
             Minor clean-up.
             Set version to v0.5.0.
       * 2019-05-10: Merge changes.
             Undo file moves.
       * 2019-05-13: Place after new v0.4.4.
       * 2019-05-17: Merge refactoring of slope parameter handling,
             and accompanying changes, with adjustments.
             Merge param module into slope module, and
             re-rename SGS_TimedParam type to SGS_Slope.
         Old branch:
          - 2018-11-27: Refactor timed param handling,
                replacing the SGS_Slope type with use of
                SGS_TimedParam, and more fully moving out
                code for parameter "running" from generator.
                Remove "attr" fields and flags.
                Improve -p printout (more 'f', added 'a', info).
          - 2018-12-01: Add SGS_TimedParam_ENABLED(),
                refactor parser and generator handling of flags.
       * 2019-05-28: Merge refactoring.
         Old branch:
          - 2019-02-10: Rename SAU_UInt8Arr to SAU_ByteArr.
       * 2019-06-05: Merge diff after v0.2.3 syntax change.
       * 2019-06-13: Set version to v0.3.0.
       * 2019-06-16: Adjust parser for new v0.2.4 syntax changes.
       * 2019-06-18: Split out v0.2.9, place after v0.2.10.
       * 2019-06-22: Set version to v0.2.11.
       * 2019-08-07: Merge Makefile -ffast-math portability fix.
       * 2019-09-12: Move down renaming of slope module to ramp.
       * 2019-12-21: Merge 'S a' multiplier apply-to-ramp fix.
       * 2019-12-24: Merge clean-up changes for v0.2.5.
             Adapt v0.2.5 changes to use 'S t' as
             default time placeholder for ramps.
       * 2019-12-25: Fix partial ramp update (using the new flag),
             after renaming it (flip to _SET instead of _DEFAULT).
       * 2020-01-03: Move down a few clean-up changes:
         Old branch:
          - 2020-01-01: Make arrtype add method return pointer to item
                in current array allocation, for initialization.
          - 2020-01-03: Compile with -pedantic, remove warnings.
                Remove the generator value-by-value ramp copying.
       * 2020-01-29: Build without -pedantic
             after fixing most warnings. System libraries
             and differing C versions make -pedantic and -std=c??
             generate spurious warnings on some systems.
       * 2020-07-22: Split out the above from
             generator changes for mixing and further modularization.
             Keep version at v0.2-beta.
             Redo naming in ramp module.
       * 2021-12-27: Change to use "%u", not "%d", in -p printouts.
       * 2022-01-10: Move down some small clean-ups.
         Old branch:
          - 2019-07-31: README typo fix & ramp.c comment fix.
          - 2020-08-22: Move down parseconv refactoring,
                including split of voicegraph from parseconv
                (formerly renamed scriptconv), from v0.3.6d.
                Break out SAU_File_end() function, from v0.3.2.
          - 2022-01-07: Undo split of parseconv/voicegraph files,
                but keep all refactoring.
       * 2022-07-11: Increase decimal digits in -p printouts to 2.
             Also move down small clean-up as part of bigger merge.
         Old branch:
          - 2020-09-19: Refactor parser scan_ramp() to
                handle both multi-value and state cases.
    • Joel K. Pettersson's avatar
      Add num. variables, expand symtab. Change 'S' scope. · 6feede28
      Joel K. Pettersson authored
      Language changes:
       * Variable syntax (formerly called "Label").
         - Add "'name=..." variation of the syntax for
           variable assignment, for assigning a number.
           Variables are now dynamically typed.
         - Add "$name" expression, for using a variable
           in a numerical expression.
       * Script options.
         - Make the "S" options lexically scoped,
           restoring the older values from outside
           a nested list when the list is exited.
         - Apply the "S a" value set inside a nested
           list to any modulators which follow at the
           same list level. Previously it only applied
           to top-level carriers.
      The variable extension is backward-compatible.
      Also remove the restriction on assigning an
      object reference to an object reference.
      Add a second layer of data to the symbol table
      beyond the string hash table. Further, planned
      features will extend it for lexical scope.
      Change numerical expression parsing to always
      return double precision numbers, so variables
      can also use that. Convert to single when such
      fields are assigned.
      Change log:
       * 2022-07-28: Symtab changes, using arrtype.
       * 2022-08-06: Remove unsafe array item use, a
             pointer returned will now remain valid.
             Add numerical variables feature.
       * 2022-08-11: Move down to sgensys.
       * 2022-08-21: Make 'S' usage lexically scoped.
  3. 21 Sep, 2022 4 commits
    • Joel K. Pettersson's avatar
      Add help module for -h <topic>. Cli & symtab clean-up. · 3d47e97c
      Joel K. Pettersson authored
      Command-line behavior:
       * Change the -h option to list topics
         available with -h <topic>. For now,
         only other lists are available, the
         first built-in help consisting of a
         'wave' type list and a 'ramp' list.
       * Print -p info for each script just prior to
         generating audio for it if done, instead of
         printing for all before generating for all.
      Parser warnings now use the new code for
      listing valid items. But a meta-list, of
      the lists to be available with -h, needs
      manual extension in help.c when more are
      added. All lists are in the same format.
      Change cli argument parsing to allow a flag to be followed
      by its argument without a space in-between. Recognize "--"
      as meaning no further strings are flags. Uses SGS_getopt()
      derived from Christopher Wellons's public domain getopt().
      Should fix the old cli non-POSIX annoyances & limitations.
      Option flag enum and handling is moved to 'sgensys.h'
      and the 'reader/reader.c' and 'player/player.c' code.
      Refactor symtab, use DJB2 hash (with length addition)
      and make copying of array-of-strings NULL-terminated.
      Change log:
       * 2020-01-18: Add help module, expand -h.
             Simple code for printing out name array,
             used for wave module. Easily extended to
             print out more lists in the same format.
       * 2020-07-23: Move to saugns
             from the 2020-06 "mgensys" experiment.
             Replace 'noise' help type with 'ramp'.
         Old branch:
          - 2020-02-10: Add noise module with noise names,
                and add help type.
       * 2020-11-12: Group -p info printing with
             other per-script output generation.
       * 2020-12-20: List 'help' help type in itself.
             Change -h to also list normal usage info
             unless a topic is named.
       * 2021-01-08: Add SSG_getopt() and use in ssndgen.c.
             Change common module license from ISC to 0BSD.
             Point the user to pass -h on cli option error.
       * 2021-07-21: Move down to new sgensys.
       * 2021-11-08: Rename discard_programs() to SAU_discard().
       * 2022-02-01: Move down further, for reasonable cli code.
         Old branch:
          - 2019-05-17: Refactor symtab without functional change.
          - 2019-06-28: Use DJB2 hash (with length addition).
          - 2019-12-27: symtab: For varying TabItem size,
                use sizeof and key[] instead of offsetof and key[1].
                (Resulting object file identical.)
          - 2020-01-03: De-const-ify ptrlist item void pointers.
          - 2020-01-26: Import from saugns v0.3.6d.
                Remove symtab get/set functions,
                rename types, expose MGS_SymStr type - used directly
                in parser to simplify code. Also changes
                to append NULL pointer to pool_stra arrays.
          - 2020-11-14: Clean up name/ver in cli strings.
          - 2020-11-20: Upgrade symtab to 2020-06 "mgensys"
                version and adapt the parser.
    • Joel K. Pettersson's avatar
      Support AUDIODEV environment variable. · b701e697
      Joel K. Pettersson authored
      Check for the AUDIODEV environment variable,
      using it to override the default device name
      regardless of which type (ALSA, OSS, ...) is
      used. Similar to handling in other software,
      e.g. SoX and SDL. Empty strings are ignored.
      For OSS only, also check OSS_AUDIODEV if the
      AUDIODEV variable wasn't used, or "default".
      Credit to Art Nikpal (@hyphop at GitHub) for
      the basic idea, and SoX code as a reference.
      Further refactor player/audiodev code a bit.
    • Joel K. Pettersson's avatar
      Fix -r 1 hang, make 96000 default. Reorganize code. · 38ae2516
      Joel K. Pettersson authored
      Move 'audiodev' and 'wavfile' modules to 'player/',
      move 'renderer.c' into 'player/' as 'player.c', and
      rename 'builder/' to 'reader/', move 'builder.c' to
      'reader/' as 'reader.c'. Rename keyword-like SGS__*
      macros to sgs* without functional change. Relicense
      'audiodev' and 'wavfile' files, from LGPL-3 to ISC.
      Rename 'test-builder' to 'test-scan' and name
      the Makefile target 'tests' instead of 'test'
      (and minimize its linkage file dependencies).
      Sort Makefile contents. Change Makefile, more
      often use -O3, but also -Os where it matters.
      Change default -r sample rate to 96000 Hz,
      undoing the 2012-02-10 change to 44100 Hz.
      Add minimum per-channel buffer length
      (currently 1 sample) in player.c, fix
      hang if/when -r 1 loops 0-length run.
      Expand 'IDEAS' file on design
      ideas, and rename 'IDEAS.md'.
      Change log:
       * 2019-12-15: Expand 'IDEAS' file, and rename 'IDEAS.md'.
       * 2020-07-22: Rename renderer part -> player
             and move the audiodev & wavfile files.
             Also includes renaming SGS__* defines,
             for consistency, to sgs* (more like in
             2020-06 "mgensys"), and relicensing of
             audiodev & wavfile from LGPL-3 to ISC.
       * 2020-07-26: Reduce diff with 2020-06 "mgensys" experiment,
             changing default sample rate to 96000 Hz (was 44100 Hz
             after 2012-02-10). Also use ISC license header for the
             common module and math.h, to keep permissive code free
             from dependencies on including non-permissive code.
       * 2020-11-09: Renaming in "player/player.c".
       * 2020-12-14: Ensure output buffer holds >= 1 sample, fix
             hang with -r 1 when 0 samples were ran in run loop.
       * 2021-07-25: Move builder.c into builder/.
             Rename "test-builder" to "test-scan".
       * 2021-10-26: Rename 'builder/', 'loader/'.
       * 2022-07-17: Move down more Makefile adjustments.
         Old branch:
          - 2021-01-12: Makefile change to use more -O3.
                Use -Os where it matters most, currently
                the parser, for avoidance of size bloat.
          - 2021-07-22: Reorder the Makefile dependencies
                in every remaining line alphabetically...
       * 2022-08-28: Rename 'loader/', 'reader/'.
    • Joel K. Pettersson's avatar
      Support running multiple scripts. Use larger output buffer. · 27945e34
      Joel K. Pettersson authored
      Support multiple script files or strings per command-line
      invocation. Also make corresponding changes to the
      'test-builder' program. (Use SGS_PtrList in main module,
      builder, and renderer for lists. Combine the old behavior
      with running through a batch of things at each stage.)
      Use 256 ms of audio output buffering in renderer.
      Fixes stuttering on NetBSD 8 (which requires >= 128 ms
      of buffering for consistently smooth playback).
      The extra 128 ms is for the sake of portability.
      (All non-NetBSD systems I personally use have however
      worked fine with the old 1024 sample buffering.)
      While at it, also increase the generator's internal
      buffer length from the ancient value of 256 samples
      to 1024. (This is simply a performance vs. memory
      use trade-off. The number of buffers could potentially
      grow into the hundreds or thousands for extreme input.
      This increases memory use fairly conservatively.)
      Const-ify pointers to non-modified SGS_Program instances.
      Change log:
       * 2019-06-04: Move multiple script args support back
             to v0.5.0, use the old version number.
         Old branch:
          - 2019-02-10: Support multiple script paths per
                command-line invocation. Also make corresponding
                changes to the 'test-builder' program.
                Move ptrlist to main dir (out of builder/).
                Increase version to v0.6.1.
                Const-ify non-modified SAU_Program pointers.
          - 2019-05-28: Merge support for multiple script args,
                and refactoring. Combine with support
                for -e <string> in the simplest way.
                Set version to v0.5.2. Update README.
          - 2019-05-29: Tweak usage notice.
       * 2019-06-18: Merge audio buffering changes.
             Move it all back to after v0.2.8,
             set version to v0.2.9.
         Old branch:
          - 2019-06-13: Increase generator buffer length
                from 256 samples to 1024 samples.
          - 2019-06-14: Change renderer output buffer
                sizing to remove stuttering on NetBSD.
                (Use 256 ms instead of 1024 samples.)
                Refactor the code in the process.
                Increase version to v0.3.2.
       * 2019-02-09: Merge changes for renderer.c,
             fixing crash on opening several files when
             only some failed to open.
             Simplify usage notice.
         Old branch:
          - 2019-06-22: Minor refactoring in renderer.c.
          - 2020-02-03: Add missing NULL checks in renderer.c;
                check for NULL programs, as is supposed to be done.
       * 2020-07-13: Keep version at v0.2-beta.
       * 2022-07-16: Makefile: Add 'fullcheck' target (-m testing).
             Allow ARGS for it and 'check' (`make check ARGS=...`).