News:

SMF for DIYStompboxes.com!

Main Menu

Audio Effects DSP Board

Started by markseel, June 13, 2016, 11:53:46 AM

Previous topic - Next topic

mhelin

Regarding ADAT most converters like my old ADA8000 can receive the word clock sync from host using a BNC cable. However, the conversion quality depends heavily on clock quality, and a local clock is usually preferred because of lesser jitter. xCORE processors can do ADAT protocol handling (NRTZ etc., example https://github.com/xcore/sc_adat ) but it might be better to use dedicated receiver like Coolaudio V1402 (from gabintechglobal.com or Behringer directly) to do the job at least if you want to do some DSP like running a cabinet simulator at the same time. Musicians usually need multiple inputs for recording but can do monitoring in stereo fine. Also when you are recording more than eight channels you must though use the sync cable, but can connect it from one converter box to another and run the host as slave.

pruttelherrie

Quote from: markseel on September 19, 2017, 02:23:57 PM
I also have this board almost ready to go.  It's much simpler so I'll make these without using a KickStarter to get production going.  If the next board rev checks out OK then they should be ready to ship in low volumes within perhaps 4 weeks.

MiniFX DSP Board (1.4" x 1.0")

Mark,

What's the status of this board, and what's the price point going to be (approximately)?

micromegas

Quote from: pruttelherrie on October 18, 2017, 05:56:44 PM
Quote from: markseel on September 19, 2017, 02:23:57 PM
I also have this board almost ready to go.  It's much simpler so I'll make these without using a KickStarter to get production going.  If the next board rev checks out OK then they should be ready to ship in low volumes within perhaps 4 weeks.

MiniFX DSP Board (1.4" x 1.0")

Mark,

What's the status of this board, and what's the price point going to be (approximately)?

+1

Also interested.
Software Developer @ bela.io

markseel

Oh man I'm so close!

Just getting the power supply and reset sequencing stable then boards are done.  Other than that they already work - just that they don't consistently reset properly when power is applied (USB jack plugged in).  That should be finished in 1-2 weeks (those boards are on order).   So boards ready for shipping in 1 month perhaps?

Then I'll take orders and in parallel start making them in low quantities (hand assembled in lots of 10 until I can scale up ... if there's demand).  $50 each for the small board.  Maybe $50 for the demo board with audio codec, I2C ADC, pots, audio jacks, etc.  So $100 for both.  A web site is being made where you can add this stuff to your cart and pay/checkout.

In the meantime I'll start making application notes for board usage to demonstrate using pots as tone/volume knobs, low-frequency oscillators, up/down sampling, real-time adjustable EQ's, IR processing (cab sim), etc.

markseel

#204
OK power supply and sequencing looks stable now.  Firmware loading via USB/MIDI is almost finished.  After that the USB/XMOS module is done!  The demo board audio (guitar level input and output) checked out OK.  Next is to make sure that the ADC on the demo board (for the pots) works and that the I2C code in the example is correct - should be done in a few days.  After that  both boards are done and ready for production.  So I'm thinking I can take orders as soon as this weekend (before the actual store is up) if early adopters are OK to do this via email/PayPal.  :icon_biggrin:

Tuff Pedals


micromegas

Count me in as well. Can't wait to give it a try
Software Developer @ bela.io

tcpoint


cliffsp8

Count me in too. And please keep me informed about the ADAT option if you still want me to test it.

Cliff

markseel

#209
I'm now ordering PCB's and parts to make 10 XMOS/DSP modules and 10 demo boards.  Here's a pic of the DSP module plugged into the demo board (note that I only soldered in one pot).  The ADC for the pots, ADC/DAC for audio, analog guitar interface, etc are all on the bottom of the board and can't be seen in this pic.



The FlexFX kit (the software dev kit) is updated and downloadable from here: https://github.com/markseel/flexfx_kit
It has the cabsim example app.  This is a stereo IR / Cabsim (30 msec per left/right channel) application with digital volume, tone and USB audio / Cabsim audio blend controls via pots.

The FlexFX kit includes a Python script (flexfx.py) that's used to download firmware and control the cabsim example.  It can load IR data stored in WAV files.  I'll add info to the FlexFX readme that shows how to use this ASAP.

If you want a DSP board + Demo Board ($100) email me (markseel@protonmail.com) and I'll put you on the list.  After these are built and I'm ready to ship you can pay via PayPal and supply a shipping address.  If you want the XTAG adapter to use with the XTAG-2 USB JTAG adapter then add $10 (total would be $110).  You don't need the XTAG adapter if you're just using the FlexFX firmware/kit - only need it if you're building custom XMOS FW from scratch.

markseel

#210
The README for the FlexFX kit has been updated with usage examples for the example host app and the utility Python scripts.  The host app script is used to update firmware and load IR files while the design scripts are used for FIR and IIR filter design (generate filter coefficients, plot responses) and for graphing time/frequency responses for audio sample data files.  https://github.com/markseel/flexfx_kit

markseel

#211
Updated the FlexFX GitHub README with this example/demonstration code and video below.  It shows how to read pots via the ADC on the demo board and then how to create a property (a collection of five 32-bit values with a 32-bit ID) and send it to the host via USB/MIDI.  There's a video that shows the 'flexfx.py' script reading these properties and printing their contents to the console via STDOUT.

From the README ...

USB Host Application

Usage #2

Indefinitely display properties being sent from the DSP board, enumerated as USB MIDI device #0, to the USB host (CRTL-C to terminate). The first six columns are the 32-bit property ID and five property values printed in hex/ASCII. The last five columns are the same five property values converted from Q28 fixed-point to floating point. These rows are printed at a very high rate - as fast as Python can obtain the USB data over MIDI and print to the console.


bash$ python flexfx.py 0
11111111  0478ee7b 08f1dcf7 0478ee7b 00dcd765 fd3f6eac  +0.27952 +0.55905 +0.27952 +0.05392 -0.17201
11111111  0472eb5b 08e5d6b6 0472eb5b 00f5625e fd3ef034  +0.27806 +0.55611 +0.27806 +0.05991 -0.17213
11111111  0472eb5b 08e5d6b6 0472eb5b 00f5625e fd3ef034  +0.27806 +0.55611 +0.27806 +0.05991 -0.17213
11111111  0478ee7b 08f1dcf7 0478ee7b 00dcd765 fd3f6eac  +0.27952 +0.55905 +0.27952 +0.05392 -0.17201
...


This video shows the 'flexfx.py' script receiving properties from the DSP board and printing them to the console.  For this example FlexFX firmware is capturing four potentiometer values, packaging them up into a property, and sending the property to the USB host (see code below).  One of the pots is being turned back and fourth resulting in changes to the corresponding property value.

https://raw.githubusercontent.com/markseel/flexfx_kit/master/flexfx.py.usage2.mp4


static void adc_read( double values[4] )
{
    byte ii, hi, lo, value;
    i2c_start( 100000 ); // Set bit clock to 400 kHz and assert start condition.
    i2c_write( 0x52+1 ); // Select I2C peripheral for Read.
    for( ii = 0; ii < 4; ++ii ) {
        hi = i2c_read(); i2c_ack(0); // Read low byte, assert ACK.
        lo = i2c_read(); i2c_ack(ii==3); // Read high byte, assert ACK (NACK on last read).
        value = (hi<<4) + (lo>>4); // Select correct value and store ADC sample.
        values[hi>>4] = ((double)value)/256.0; // Convert from byte to double (0<=val<1.0).
    }
    i2c_stop();
}
void control( int rcv_prop[6], int usb_prop[6], int dsp_prop[6] )
{
    // If outgoing USB or DSP properties are still use then come back later ...
    if( usb_prop[0] != 0 || usb_prop[0] != 0 ) return;
    // Read the potentiometers -- convert the values from float to Q28 using the FQ macro.
    double values[4]; adc_read( values );
    // Create property with three Q28 pot values to send to USB host
    usb_prop[0] = 0x01010000; dsp_prop[4] = dsp_prop[5] = 0;
    usb_prop[1] = FQ(values[0]); usb_prop[2] = FQ(values[1]); usb_prop[3] = FQ(values[2]);
}



markseel

Here's another demo - cabinet simulation!  From the GitHub FlexFX README:

Example Application

Stereo Cabinet Simulation with Tone/Volume and USB Audio Mixing. See this video for a demonstration. The firmware is first written to FLASH memory using the 'flexfx.py' script. After that the firmware reboots and enumerates as a USB audio device resulting in audio. The first few chords are sent from the guitar ADC to the line out DAC unprocessed. The 'flexfx.py' script is then used to load an IR file called 'ir1.wav'and then used to load another IR file called 'ir2.wav'. The firmware is performing 25 msec of IR convolution (at a 48 kHz audio sample rate) on both left and right audio channels using 32/64 bit fixed-point DSP.

https://raw.githubusercontent.com/markseel/flexfx_kit/master/app_cabsim.mp4

markseel

Here's a two-voice chorus demo with source code and a video.

I used a 48 kHz sampling rate and 2nd order interpolation to smooth out the sine wave look-up table (for two LFO's) as well as the sub-sampling of the delay line.  Another approach would be to use 1st order interpolation and up/down sample before/after the chorus effect but that will be another example.  From the GitHub FlexFX README (way at the bottom!)

Example Application #2 - Chorus

Chorus example with two voices showing how to create LFO's and how to use 2nd order interpolation. See this video for a demonstration of building and loading the firmware exmaple, and the chorus audio effect. https://raw.githubusercontent.com/markseel/flexfx_kit/master/app_chorus.mp4

pruttelherrie

A follow-up on the possibilities for a UI for a multichannel audio interfaces based on the FlexFX boards.

During a slightly boring meeting at work today I re-discovered both OSC and Python.

I realised that my DAW of choice -Reaper- can output OSC messages following UI/track changes. So I dived in and tested a bit. I mangled the server example from python-osc and added some stuff from your (Mark's) flexfx.py script. The resulting server filters Reaper's UI changes and transforms them into Properties which are sent to the USB MIDI FlexFX board. It's then up to the board's firmware to do the DSP-mixing of the interface based on these properties.

The nice thing of this is that one can then have the FlexFX mixer setting *in* the Reaper UI! See attached screenshot. I twiddled the first 4 channels in Reaper a bit and the server prints some info on the filtered OSC messages. With python-rtmidi the correct Properties can then be sent to the Flex FX board. The tracks that are used for the FlexFX mixer UI have a blue header and are also made invisible in the track window (the upper part of Reaper) so one won't use them for audio.
(The python script below still needs to be adapted to the number of channels and the required transformations from OSC values to 32-bit property values.)

*opens a beer*

Cheers!



"""Small example OSC server

This program listens to several addresses,
and prints some information about
received packets.
"""

import argparse
import math
import sys, time, struct, rtmidi

from pythonosc import dispatcher
from pythonosc import osc_server

def property_to_midi_sysex( property ):
  midi_data = [0xF0]
  for x in range (0,5):
    for y in range (0,7):
      midi_data.append( (property[x] >> (28-y*4)) & 15 )
    midi_data.append( 0xF7 )
    return midi_data

def midi_write( midi_device, midi_sysex_data ):
  midi_device.send_message( midi_sysex_data )

def pan_handler(addr, args, value):
  track = int(addr[7:8])
  print("{0} / {1} / {2} / {3}".format(addr, track, value,
                                   int(value * (2 **31))))
  data=[ 0x06660000 + track, int( value * (2 ** 31) ), 0, 0, 0 ]
  midi_write( midi, property_to_midi_sysex( data ))

def volume_handler(addr, args, value):
  track = int(addr[7:8])
  print("{0} / {1} / {2}".format(addr, track, value))

def mute_handler(addr, args, value):
  track = int(addr[7:8])
  print("{0} / {1}".format(addr, value))

def solo_handler(addr, args, value):
  track = int(addr[7:8])
  print("{0} / {1}".format(addr, value))

if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.add_argument("--ip",
      default="127.0.0.1", help="The ip to listen on")
  parser.add_argument("--port",
      type=int, default=5005, help="The port to listen on")
  args = parser.parse_args()
  midi = rtmidi.MidiOut()
  dispatcher = dispatcher.Dispatcher()
  dispatcher.map("/track/*/pan$", pan_handler, "Pan")
  dispatcher.map("/track/*/volume/db$", volume_handler, "Volume")
  dispatcher.map("/track/*/mute$", mute_handler, "Mute")
  dispatcher.map("/track/*/solo$", solo_handler, "Solo")

  server = osc_server.ThreadingOSCUDPServer(
      (args.ip, args.port), dispatcher)
  print("Serving on {}".format(server.server_address))
  server.serve_forever()


markseel

#215
Nice work!  How many audio channels were you thinking of using?  I'll make a high channel-count mixer example.

pruttelherrie

I was thinking of 16 in and 4~8 out (2~4 stereo outputs).

At the moment I only have an 8-channel ADAT interface; I'm still figuring out if I'm going to go for multichannel I4S or I8S codecs, plus preamps, or go the 2pcs 8-channel ADAT route. The latter is simpler hardware-wise, but I'll need ADAT support for that in the firmware ;)

For the outputs I'll have to make groups or busses in the Reaper template, so that each output-pair can have its own mix.

markseel

ADAT out from the FlexFX or ADAT input to the FlexFX?

pruttelherrie

Ehm.. both. Mic preamps -> ADAT -> FlexFX, and then the mixed* signals from FlexFX -> ADAT -> headphoneamps+monitors

* mixed = (stereo) USB audio + the inputmix, if that makes sense. I'll make a diagram one of these days.

markseel

Is a word-clock available?  If not then a PLL is needed to recover the clock information embedded in the ADAT serial bit stream.  Not hard to make but it does add cost.