Real time bit inversions of audio signal

I guess this is a bit of an "is this possible" with arduino (or Teensy?) question:

there's a very cool audio effects box called and OTO Biscuit, now discontinued/rare/expensive. I'd like to try and work out something similar DIY if I can.....

One of it's effects is that by means of button push it can invert or mute each of the bits of an 8 bit audio signal.
Is this something it is possible to do with arduino?

I am not too bad at building electronics, but pretty appalling at coding, so any tips of a good place to start my research for this sort of thing would be gratefully received.

I am guessing the code needs to read the incoming digital audio and then mute or invert IF based on a button push/switch, so I can sort of see how it would work, but I am a bit unsure how exactly you'd instruct an Arduino to read the individual bits, and if it is fast/powerful enough to do this in real time?

the attached schematic shows how the original is configured - i'm reasonably confident of working out most of it - but not quite sure where to start with what goes on in the microcontroller..

thanks in advance!

You are better off with a DSP for that project. Most Arduinos do not have a reasonable sampling rate, processing power and analog output for stereo sound.

One of it's effects is that by means of button push it can invert or mute each of the bits of an 8 bit audio signal.
Is this something it is possible to do with arduino?

Yes given the limits of sample rate and resolution if the Arduino the actual processing you need to do to the data is trivial.

To invert a bit you simply “exclusive or” the sample with a number that has logic ones in each position you need to invert.

To mute ( or set to zero ) you just do a “logic and” operation between the sample and a number that has logic zeros in each bit position you want to zero.

Each of this is just one instruction, you can’t get much simpler than that. However I can’t see it sounding in any way interesting, you are just putting random spikes in the waveform.

ok, thanks - will look into that (bit concerned this moves it further away from my coding abilities though!)

DSP was a very helpful search term!

I found this... http://www.instructables.com/id/Arduino-Vocal-Effects-Box/

which seems to be managing to do 40Khz with granular synthesis and external DAC...

If I am understanding the schematic halfway down correctly.... is it actually outputting each "bit" of audio on a separate digital pin here?

If so I am wondering whether I can avoid the complicated coding altogether and just use switches to introduce/remove hex inverters into the circuit at this point, achieving the same thing (or something else interesting!)

(I may be missing something entirely here)

If so I am wondering whether I can avoid the complicated coding altogether

What complicated coding, it is just one line for God’s sake?

the_duckchild:
One of it's effects is that by means of button push it can invert or mute each of the bits of an 8 bit audio signal.
Is this something it is possible to do with arduino?

Bitwise manipulation is a pretty trivial operation and for 8 bit values would run fast enough on any Arduino e.g.

sampleOut = sampleIn & B11110111 ;     // "mute" bit 3 of sampleIn using bitwise AND mask
. . .
sampleOut = sampleIn ^ B00001000 ;     // "invert" bit 3 of sampleIn using bitwise XOR

I am guessing the code needs to read the incoming digital audio and then mute or invert IF based on a button push/switch, so I can sort of see how it would work, but I am a bit unsure how exactly you'd instruct an Arduino to read the individual bits, and if it is fast/powerful enough to do this in real time?

Using the analogRead() function and the internal A/D converter is relatively slow for normal audio sampling rates, but might be adequate for single channel proof of concept. It's possible to run faster using continuous sampling modes but this requires register level coding. analogWrite() on most 8-bit Arduinos probably isn't sufficient for this application so an external D/A would be required.

With a Teensy I expect one could do two channel A/D, D/A, and filtering all in software.

Grumpy_Mike:
What complicated coding, it is just one line for God’s sake?

yes, sorry - that was in answer to the previous post about using a DSP chip!

Grumpy_Mike:
Each of this is just one instruction, you can’t get much simpler than that. However I can’t see it sounding in any way interesting, you are just putting random spikes in the waveform.

thanks!

I think the thing is you are putting spikes and/or drops in the waveform over time at quite low bit depth and sample rate, so it sounds pretty gnarly and lofi and distorted - the idea is that this signal can then be analogue filtered and/pr mixed with the clean signal.

or I am misunderstanding what the original box does. Which is possible, I am not expert!

from a review of the box:

"each switch represents one of the eight bits of the signal with the least significant bit at the left hand end and the most significant bit at the right. Clicking a switch toggles it through three states (on/inverted/muted) and the severity of the resultant distortion increase the further to the right the bits are inverted or muted.

The clock knob meanwhile sweeps the internal sample rate down"

thing is you are putting spikes and/or drops in the waveform over time at quite low bit depth

The depth or height of these spikes depends on which bit or bits you are choosing to mess up. If it is the most significant bit then this is half the waveform.

for sure, as that link suggests, the MSB makes much more difference and it can get pretty loud.

here's the original thing:

re: "The depth or height of these spikes depends on which bit or bits you are choosing to mess up. If it is the most significant bit then this is half the waveform."

I think if I understand it right the value of the change it makes depends on what value the other 8 bits are at any given 20,000th of a second though doesn't it? (at 20khz)

if the other seven bits are "1" or "0" then it halves the current amplitude. If they're not, then it varies?

which is probably how it sounds interesting as an effect.

I think if I understand it right the value of the change it makes depends on what value the other 8 bits are at any given 20,000th of a second though doesn't it? (at 20khz)

Not quite.

For muting it depends on what the other bits are doing as to what the overall distortion would be. For example muting the most significant bit would have no effect if the peak audio signal is less than half.

For inverting the effect is always the same no matter what the other bits are doing. Again if you consider the most significant then the distortion spike in the waveform will always be half the maximum amplitude.

ah. thanks - I think I am unclear on the difference between muting and inverting.... (or some other error!)

My basic grasp of it was that the output is essentially a number between 0 and 255 once it's combined

in which case (eg) 10001000 is 136, whilst 00001000 is 8? and 11111111 is 255, and 01111111 is 127?

My other assumption was that muting would essentially bitshift everything after the bit muted (maybe?)

in which case (eg) 10001000 is 136, whilst 00001000 is 8? and 11111111 is 255, and 01111111 is 127?

Yes that is correct.

My other assumption was that muting would essentially bitshift everything after the bit muted

What ever it is, it is not that.

Grumpy_Mike:
Yes that is correct.
What ever it is, it is not that.

I realised that after I posted it. I think it's just "sending a constant zero", which is of course different to "inverting what it's sent"

If the audio is already in digital format, such as I2S, S-PDIF or even a USB stream then the Teensy can do this for you very easily. It would use a tiny fraction of the processor's abilities.

I think it's just "sending a constant zero",

Which is what I said and told you how to do.

Just some random thoughts...

  • The "regular Arduino" doesn't have a DAC (digital-to-analog converter) so you can't get analog audio out. I don't know about the Teensy.

  • The first step would be read-in analog through the ADC and then write-out analog through the DAC. If that works (without affecting/damaging the sound) it's easy to do a volume adjustment... That's about the easiest DSP you can do... i.e. Multiply each sample by 0.5 and that's a -6dB volume reduction.

  • If you want to work in 8-bits, you'll have to scale-down. (The regular Arduino ADC is 10-bits.)

  • The Audacity* website has an easy little introduction to [u]how digital audio works[/u].

  • Since the Arduino can't read (or write) negative voltages, you generally have to bias the input (and the output). Typically, you'd subtract-out the bias (so silence reads zero) but it's kind-of up to you. 8-bit WAV files use unsigned integers, so silence is 127. That's just a "strange" characteristic of 8-bit WAVs. A normal audio DAC (or the drivers) will take-out that bias so the signal swings positive and negative. Higher-bit depth WAV files use signed integers. But again, that's just the WAV standard. (Most "real" DSP is done in floating-point but floating-point with the Arduino or Teensy would probably be too slow and it's not necessary for bit-crushing.)

  • You should understand how numbers are stored in binary and [u]bitwise operations[/u]. You need to know that with signed integers the most significant bit is the sign-bit and you need to understand [u]two's complement[/u].

Of course everything in the computer is binary (and C/C++ automatically converts input/output to/from decimal by default). This probably isn't necessary for your application but programmers working with binary numbers often use hexadecimal. You can "easily" learn to convert numbers of any size between hex and binary in your head. Conversion between binary and decimal isn't so easy.

there's a very cool audio effects box called and OTO Biscuit,

I believe that's a [u]bit crusher[/u] As I understand it, a bit crusher zeros-out the less-significant bits (bits to the right). That lowers the resolution and increases the quantization noise. Quantization noise is a bit different from "regular" noise because it goes-away when there is no signal (it's kind-of like adding noise and then adding a noise gate). But just like regular noise, it's most-noticeable at low levels and at higher levels the noise tends to get drowned-out. (You can hear quantization noise if you convert a 16-bit or 24-bit audio file to 8-bits.)

Another way to loose resolution is to divide the number and then multiply (with integers... nothing to the right of the decimal point). Let's say you have 54321... if you divide that by 100 you get 543. If you then multiply by 100 you get 54200 (about the same number but rounded, with less resolution).

Zeroing-out bits is pretty easy to do, but two's compliment will require a little "thinking".

BTW - If you do the opposite and zero-out the more-significant bits (to the left) you get [u]clipping[/u] with louder sounds (regular-old distortion). But of course, don't throw-away the sign bit unless you want some terrible distortion!

  • If you want to "play around" with DSP without building hardware, Audacity has a programming language called [u]Nyquist[/u]. It doesn't work in real time, but you can create your own effects and apply them to a file.

I believe that's a bit crusher

No that is not what the OTO Biscuit's does, although the video suggests that there is one knob that will do that. It's main action is on individual bit positions.

thank you for the help, it is much appreciated!
my slight confusion was around why if this is true:

"10001000 is 136, whilst 00001000 is 8 AND 11111111 is 255 while 01111111 is 127"

the effect of inverting the msb is always to halve the amplitude.
But I can breadboard it and find out if it sounds interesting or not anyway!

the effect of inverting the msb is always to halve the amplitude.

Well in practice a sound wave is normally biased at the half way point, so that takes a maximum value and reduces it to zero as far as the wave is concerned, but to half as far as the absolute value is concerned.

my slight confusion was around why if this is true

Not sure why, see here Binary number - Wikipedia

But I can breadboard it and find out if it sounds interesting or not anyway

You can. Might try it myself in fact later on today. I’ll let you know if I can find time.