19 ms·
Using ASCII waveforms to test real-time audio code
- munchler 5y agoThis is great. People are doing very cool things with F# these days.
- jwosty 5y agoThanks, I like to think so! I didn't see other people doing much audio programming in F#, so I figured someone would be interested in seeing what it can look like.
- brianberns 5y agoFWIW, you might like this: https://github.com/brianberns/FYampaSynth https://github.com/brianberns/FYampaSynth
- jwosty 5y agoThat looks right up my alley, thanks for the link!
- rbanffy 5y agoIf we go beyond ASCII, Unicode specifies 2x2 mosaics since ever (they were present in DEC terminals) and 2x3 mosaics (from Teletext and the TRS-80) since version 13. Some more enlightened terminals (such as VTE) implement those symbols without the need of font support. Or you can use Braille to get 2x4 mosaics, but they usually look terrible.
- jwosty 5y agoI just might have to try this next.
- db48x 5y agoFor audio you might also consider U+2581—U+2588, LOWER ONE EIGHTH BLOCK through FULL BLOCK. And then if you really want to go all out there are sixels, but that’s basically just an image; you probably lose the easy ability to compare them. On the other hand they’re not available in every terminal.
- rbanffy 5y agoThese blocks are great if you need more vertical than horizontal resolution. There are also newer symbols in the Unicode 13 spec that are just the line without the fill.
- db48x 5y agoOooh, I didn’t know about those! I’m going to go look them up.
- rbanffy 5y agoThere are more details here: https://en.wikipedia.org/wiki/Symbols_for_Legacy_Computing https://en.wikipedia.org/wiki/Symbols_for_Legacy_Computing The same group wants to include a couple others, from different platforms, but the Unicode Script Ad Hoc Group is concerned the new batch may not be as meaningful as the first one.
- user-the-name 5y agoImagine if we had terminals that could handle graphical data. We wouldn't have to do weird kludges like this, we could just plot the waveforms in the output of our tools. But it's 2021, and not only is this not possible, there is not even a path forward to a world where this would be possible. It's just not an option. Nobody is working on this, nobody is trying to make this happen. We're just sitting here with our text terminals, and we can't even for a second imagine that there could be anything else. It's sad, is what it is.
- thanatos519 5y agoMaybe you would like to support https://ctx.graphics/ https://ctx.graphics/
- HPsquared 5y agoNotebook interfaces are basically that, e.g. Jupyter or Mathematica.
- voldacar 5y agoIn TempleOS you can mix text, images, hyperlinks, and 3d models in the terminal. This is true for the whole system: you could literally have a spinning 3d model of a tank as a comment in a source file. That's right, it took a literal schizophrenic to make an OS with a feature that should have been standard decades ago. Nobody tries to make actually interesting new operating systems anymore. OS research today is just "let's implement unix with $security_feature", nobody is actually trying to make computers more powerful or fun to use, or design a system based off of a first-principles understanding of what a computer should be. God I wish I was born in the lisp machine timeline
- woodrowbarlow 5y agothe downside of rich terminal output is that media formats become the system's responsibility. applications can't output media in formats that aren't provided by the system, because then the terminal wouldn't know how to display it and interop with other applications (e.g. piping) wouldn't work either.
- phab 5y agoThis approach is neat for observability, but it's worth noticing that it essentially quantises all of your samples down to the vertical resolution of your graph. If you somehow introduced a bug that caused an error that was smaller than the step size then these tests wouldn't catch it. (e.g. if you somehow managed to introduce a constant DC-offset of +0.05, with the shown step size of 0.2, these tests would probably never pick it up, modulo rounding.) That said, these tests are great for asserting that specific functionality does broadly what it says on the tin, and making it easy to understand why not if they fail. We'll likely start using this technique at Fourier Audio (shameless plug) as a more observable functionality smoke test to augment finer-grained analytic tests that assert properties of the output waveform samples directly.
- PaulDavisThe1st 5y agoA more accurate and only slightly more complex process for this is to generate numerical text representations of the desired test waveforms and then feed them through sox to get actual wave files. The numerical text representations are likely even easier to generate programmatically than the ascii->audio transformation.
- theptip 5y agoWhat does a "numerical text representation" of a waveform look like? (Not familiar with audio processing but interested to understand your suggestion.)
- PaulDavisThe1st 5y agoHere's a fragment of the representation of a stereo file: 4.9600227 0.094451904297 -0.014831542969 4.9600454 0.089172363281 -0.0092468261719 4.960068 0.087493896484 -0.0065612792969 4.9600907 0.090179443359 -0.0028686523438 4.9601134 0.093963623047 0.0060729980469 4.9601361 0.095367431641 0.020538330078 4.9601587 0.094299316406 0.035186767578 4.9601814 0.09228515625 0.045013427734 4.9602041 0.089691162109 0.051422119141 4.9602268 0.086059570312 0.058929443359 Columsn are: [time in seconds] [left channel sample] [right channel sample] This was generated using sox somefile.wav somefile.dat You can reverse that by reversing the argument order above.
- focom 5y agoWould love to use it as a library! Is it open source?
- jwosty 5y agoI've added an fssnip for the ASCII renderer. It uses NAudio. Should be pretty easy to use. http://www.fssnip.net/85g http://www.fssnip.net/85g
- jwosty 5y agoNot yet, but it certainly could be. Would it be useful to publish the helper classes that render the waves out to ASCII? That's really the guts of the thing. After that, you just use whatever testing framework you want to do the actual diffing (in my case Expecto for F#).
- spicybright 5y agoWhy would you use ascii for something like a waveform, something that's inherently a graph? Sure, maybe you don't need that much resolution for what the use case is. But it's the equivalent of looking at a graph and squinting your eyes to blur it.
- deleted 5y ago[deleted]
- jwosty 5y agoIn short, because text is much easier to deal with than bitmaps, and there is much more tooling that "just works" for text than actual graphics, like Expecto's textual diffing in assertations. @MayeulC said it well: https://news.ycombinator.com/item?id=28856884 https://news.ycombinator.com/item?id=28856884
- rbanffy 5y agoAm I the only one almost offended by Braille not being ASCII? edit: Yes. I miscalculated the dot density. /me slaps forehead
- thewakalix 5y agoAren't those asterisks?
- rbanffy 5y agoOh... The shame... Yes. I miscalculated the dot density. :-(
- bitwize 5y agoThat's so cool, and reminds me of how I used Gnuplot as a makeshift oscilloscope to test and evaluate some (not real time) software synthesis I was doing.
- necubi 5y agoThis is such a great idea! I've really struggled with how to test real-time audio code in the live looper I've been working on [0]. Most of my tests use either very small, hand-constructed arrays, or arrays generated by some function. This is both tedious and makes it very hard to debug test failures (especially with cases like crossfades, pan laws, and looping). I love the idea of having a visual representation that lets me see what's going wrong in the test output, and I'm definitely going to try to implement some similar tests. I'm also curious what the state-of-the-art is for these sorts of tests. Does anyone have insight into what e.g., ableton's test suite looks like? [0] http://github.com/mwylde/loopers http://github.com/mwylde/loopers
- jwosty 5y ago> I'm also curious what the state-of-the-art is for these sorts of tests. Does anyone have insight into what e.g., appleton's test suite looks like? I don't know, but if I were to make an educated guess, maybe rendering stuff to actual audio files is a common approach? That way when something goes wrong, they can inspect it in a standard waveform editor?
- robotsteve2 5y agoOnce you've got the waveforms as arrays, what do you need the ASCII rendering for? Instead of diffing ASCII-rendered waveforms, save the arrays and diff the arrays (and then use any kind of numerical metric on the residual). Scientist programmers have all sorts of techniques for testing and debugging software that processes sampled signals.
- jwosty 5y agoIt's usually gonna be easier to tell what went wrong in an ASCII string array than a raw float[]. It's for the human reading/fixing the test.
- icapybara 5y agowell you don't read the residual, you plot it. the ASCII plots have limited rendering resolution compared to a proper plotting system, like where you can zoom in and stuff.
- sudara 5y agoNice! I became obsessed with rendering sparkline representations of chunks of audio for the same reason: to inspect failures when writing tests / refactoring. I wrote a JUCE module (C++) and integration with lldb to make it quick to inspect chunks of audio in the IDE: https://github.com/sudara/melatonin_audio_sparklines https://github.com/sudara/melatonin_audio_sparklines
- FigBug 5y agoI was inspired by your work to do a juce implementation: https://github.com/FigBug/Gin/commit/30aa84130f4f607bdeba538b9c6c28b2dfa971bc https://github.com/FigBug/Gin/commit/30aa84130f4f607bdeba538... I think the most useful thing for me is I can call it from lldb and immediately dump buffers to my terminal while debugging.