DIYstompboxes.com

DIY Stompboxes => Digital & DSP => Topic started by: markseel on June 13, 2016, 11:53:46 AM

Title: Audio Effects DSP Board
Post by: markseel on June 13, 2016, 11:53:46 AM
This board just went out to OSHPark and should be back in a couple of weeks.  It has:

1 - One XMOS 1000 MIPs processor with 512K RAM total and 32/64 bit fixed point DSP support
2 - USB interface for USB audio streaming, effects control, firmware updating, and USB MIDI support
3 - UART/serial TX/RX for effects control, firmware updating, and/or MIDI support *
4 - JTAG interface for programming using xTIMEcomposer from XMOS, full XTAG connectivity support
5 - 48k 24-bit audio CODEC with analog interfaces on-board - can be modified to support up to 192 kHz
6 - High-impedance differential input for guitar (can be used as single-ended)
7 - Differential mono or single-ended stereo line-level output - can be modified for instrument level
8 - Small footprint - 1.0" x 1.6"
9 - Requires only single 5V supply or dual 5V digital/analog supplies - no external components needed *
* 3.3V UART TX/RX provided, MIDI support requires proper MIDI interface circuitry
* USB requires USB connector and ESD protection diodes for D+, D-, and Vbus.

(http://i1064.photobucket.com/albums/u361/markseel/flexfx-core.png)
Title: Re: Audio Effects DSP Board
Post by: markseel on June 13, 2016, 06:31:30 PM
Firmware Image Availability

XMOS firmware images (FW) for the following are planned:

1) FW #1 - USB Audio, audio mixer, stereo spatialization, and HiRes cabinet simulation
2) FW #2 - USB Audio, audio mixer, stereo spatialization, and stereo guitar multi-effects.
3) FW #3 - #1 and #2 combined with cab-sim limited to LoRes and guitar effects limited to mono.

Firmware can be uploaded via USB/MIDI, serial UART/MIDI, or via the JTAG conntector.

USB audio input allows a mix of guitar input and effects output to be routed to the USB host for monitoring and/or recording. USB output allows for mixing USB host output audio with effects output (for jamming or for re-amping).  These signal path variations are supported via three internal mixers. A stereo 15-band graphic EQ is placed at the end of the audio chain.

Configuration via serial/UART

The UART RX/TX signals can be used to upload property configuration data.
Properties are sent via RX five 32-bit values at a time preceeded with the 16-bit property ID.
An acknowledgment is sent via TX back to the host controller.
The CRC is computed as the XOR of all 22 bytes (2 bytes if ID, 20 bytes of data).
The UART settings are 230400 baud, on stop bit, no parity.

Configuration format and example is shown below:

Property ID = 0x1301
Param 1     = 0x11223344
Param 2     = 0x55667788
Param 3     = 0x99aabbcc
Param 4     = 0x01234567
Param 5     = 0x89abcdef

Step 1: RX signal <---- | Property ID | Param 1     | Param 2     | ...| Param 5     | CRC |
                        | 13, 01      | 11,22,33,44 | 55,66,77,88 |... | 89,ab,cd,ef | ??  |

Step 2: A minimum of a 200 usec delay, host should be ready to RX 200 usec after last TX

Step 3: TX signal ----> | Property ID |
                        | 13, 01      |

The acknowledgement data is equal to the property ID being updated.
A value of 0x0000 indicates an error (invalid property ID or CRC failure).

Configuration via USB MIDI

The parameter upload format uses the serial/UART format described above encapsulated within MIDI sysex messages.
See the 'configuration via serial/UART' above.

MIDI Sysex messages start with 0xF7, end with 0xF0, and contain 7-bit values (octets with MSB=0).
Therfore the 22-byte property upload byte sequence needs to be split into ~25.14 bytes.

Example using ficticious data for illustration only:

Raw property data:          Hex    - 0xA1, 0xB2, 0xC3, 0xC4 ...
                            Binary - 10100001, 10110010, 11000011, 01110100, ...

8-bit to 7-bit for Sysex:   Binary - 01010000, 01101100, 01011000, 001101110, 0100, ...
                            Hex    - 0x50, 0x6C, 0x58, 0x3E, 0x4?, ...

MIDI Sysex property data:   Hex    - 0xF7, 0x50, 0x6C, 0x58, 0x3E, 0x4?, ... 0xF0


Run-time Audio Processing Properties

Each firware supports a set of properties that determines the audio processing behavior.
Properties have a 16-bit identifier formmatted as follows:

0x1ABC where A is the 4-bit property class and BC are the 8-bit property values index.

Property Summary for Firmware #1

=================================================================================================
Property Name       ID       Param1  Param2  Param3  Param4  Param5   Notes
=================================================================================================
Mixer Control       1100     Volume  Mixer1  Mixer2  Mixer3  Reserved
-------------------------------------------------------------------------------------------------
Spatialization      1200     Enable  TBD     TBD     TBD     TBD      Converts mono to stereo   
-------------------------------------------------------------------------------------------------
GraphicEQ Flags     1300     Enable  Level                            Disable is same as bypassed
GraphicEQ Band 1a   1301     B0      B1      B2      A1      A2       Biquad coefficients
GraphicEQ Band 1b   1302     B0      B1      B2      A1      A2       Biquad coefficients
GraphicEQ Band 2a   1303     B0      B1      B2      A1      A2       Biquad coefficients
GraphicEQ Band 2b   1304     B0      B1      B2      A1      A2       Biquad coefficients
...
GraphicEQ Band 15a  132d     B0      B1      B2      A1      A2       Biquad coefficients
GraphicEQ Band 15b  132e     B0      B1      B2      A1      A2       Biquad coefficients
-------------------------------------------------------------------------------------------------
CabSim Data Flags   1400     Enable                                   Disable is same as bypassed
CabSim Data, Next   1401     N+0     N+1     N+2     N+3     N+4      Next set of 5 blockA values
CabSim Data, Last   1402     N+0     N+1     N+2     N+3     N+4      Last set of 5 blockA values
...
CabSim Data, Next   1409     N+0     N+1     N+2     N+3     N+4      Next set of 5 blockE values
CabSim Data, Last   140a     N+0     N+1     N+2     N+3     N+4      Last set of 5 blockE values
=================================================================================================


Property Summary for Firmware #2

TBD, includes mixer, spatialization and graphic EQ properties plus guitar effects properties.


Property Summary for Firmware #3

TBD, includes mixer, spatialization and graphic EQ properties plus a reduced set of cabinet sim
IR and guitar effects properies.


Mixer Control (Firmwares #1 #2 #3, ID 0x1100)

Volume and level are 32-bit Q1.31 values used to scale the signal from 0 to 0.999...
Mixer values are 32-bit Q1.31 fixed point values with ~0.5 representing a 50/50 mix.

[Guitar]-----+-------------------------[Mixer2]---->[USB In]
             |                            /\
             |                            |
             \/                           |
          [Mixer1]--->[Effects]--->[Spatialization]
             /\                           |
             |                            |
         (Left Ch.)       +---------------+
             |            |
             |            \/
[USB Out]----+-------->[Mixer3]--->[GraphicEQ]--->[Volume]--->[Line Out]


Stereo Spatilization (Firmwares #1 #2 #3, ID 0x1200 through TBD)

Converts mono to stereo.


Graphic EQ (Firmwares #1 #2 #3, ID 0x1300 through 0x131b)

15 band graphic EQ.
Each band's frequency response is determined by a two-cascade biquad IIR filter.
Each band's 10-value coefficient data (for two biquads) is set via two properties (5 values each).
Biquad coefficients are formatted as 32-bit Q4.28 fixed-point values.


Cabinet Simulation, HiRes (Firmware #1, ID 0x1400 through 0x1402)

Speaker cabinet and/or acoustic response simuation via time-domain convolution.
Up 62 msec (mono HiRes) of impulse response is supported via 3000 IR coefficients.
Up 31 msec (stereo LoRes) of impulse response is supported via 3000 IR coefficients.
Impulse response data is loaded 5 impulse response values at a time (see serial/UART format).
3000 impulse response values are split into blocks (A, B, C, E, and F) of 600 IR values each.
For stereo LoRes the left channel's 1500 values are loaded first, right channel is second.
'Next' is used for all IR data loading with the exception of the last 5 values using 'Last'.
Impulse response values are formatted as 32-bit Q1.31 fixed-point values.

Cabinet Simulation (Firmware #3, ID 0x1400 through 0x1402)

Speaker cabinet and/or acoustic response simuation via time-domain convolution.
Up 31 msec (mono LoRes) of impulse response supported via 1500 IR coefficients.
Impulse response data is loaded 5 impulse response values at a time (see serial/UART format).
1500 impulse response values are split into blocks (A, B, partial C) of 600 IR values each.
'Next' is used for all IR data loading with the exception of the last 5 values using 'Last'.
Impulse response values are formatted as 32-bit Q1.31 fixed-point values.
Title: Re: Audio Effects DSP Board
Post by: markseel on June 13, 2016, 07:15:23 PM
One can create custom audio processing effects by downloading the audio processing framework (to be provided via GitHub - coming soon), adding customer audio processing DSP code, build using XMOS tools (xTIMEcomposer).  The customer firmware can then be burned to FLASH using xTIMEcomposer and the XTAG-2 or XTAG-3 JTAG board ($20 from Digikey), via USB/MIDI, or via serial/UART MIDI (there are special properties defined for firmware upgrading and boot image selection).

The audio processing framework on GitHub implements the USB class 2.0 audio and USB MIDI interfaces, the I2S/CODEC interface, the serial/UART interface, USB/ADC/DAC audio mixing, 15-band graphic EQ, property/parameter transfers, and firmware upgrading.

All one has to do then is add DSP code and any relevant custom property handling code to the five audio processing loops which all run in parallel and implement a five stage audio processing pipeline.  Each processing thread is allocated 100 MIPS of the total 500 MIPs available and executes once per audio cycle (48 kHz).  All threads are executed once per audio cycle.

static void _copy_prop( int dst[5], const int src[5] )
{
    dst[0] = dst[0]; dst[1] = dst[1]; dst[2] = dst[2];
    dst[3] = dst[3]; dst[4] = dst[4];
}

int audio_thread_1( const int input[2], int output[2], int prop_id, const int prop_data[5] )
{
    static int example_property1_params[5]; // Example property ID = 0x1801
    static int example_property2_params[5]; // Example Property ID = 0x1802
   
    switch( prop_id )
    {
        case 0x1801: _copy_prop( example_property1_params, prop_data ); prop_id = 0; break;
        case 0x1802: _copy_prop( example_property2_params, prop_data ); prop_id = 0; break;
    }
   
    output[0] = input[0]; // Pass through left channel unmodified
    output[1] = input[1]; // Pass through right channel unmodified
   
    return prop_id; // Zero indicates that property data was consumed and should be cleared
}

int audio_thread_2( const int input[2], int output[2], int prop_id, const int prop_data[5] )
{
    output[0] = input[0]; // Pass through left channel unmodified
    output[1] = input[1]; // Pass through right channel unmodified
   
    return prop_id; // Zero indicates that property data was consumed and should be cleared
}

int audio_thread_3( const int input[2], int output[2], int prop_id, const int prop_data[5] )
{
    output[0] = input[0]; // Pass through left channel unmodified
    output[1] = input[1]; // Pass through right channel unmodified
   
    return prop_id; // Zero indicates that property data was consumed and should be cleared
}

int audio_thread_4( const int input[2], int output[2], int prop_id, const int prop_data[5] )
{
    output[0] = input[0]; // Pass through left channel unmodified
    output[1] = input[1]; // Pass through right channel unmodified
   
    return prop_id; // Zero indicates that property data was consumed and should be cleared
}

int audio_thread_5( const int input[2], int output[2], int prop_id, const int prop_data[5] )
{
    output[0] = input[0]; // Pass through left channel unmodified
    output[1] = input[1]; // Pass through right channel unmodified   
   
    return prop_id; // Zero indicates that property data was consumed and should be cleared
}
[/font]
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on June 13, 2016, 11:02:22 PM
Mark this is very cool.  As you know, I hate writing DSP code so much I'm willing to write thousands of lines of Java just to avoid it.  :icon_wink:  I recently got a Blackfin DSP eval board, thinking to possibly leverage something like Pure Data through "Heavy" I think it is called, to be able to create more powerful FX than one can accomplish on the FV-1.  Do you think there's any possibility that your board would be compatible with that approach?

See: https://enzienaudio.com/

Regards,

DL
Title: Re: Audio Effects DSP Board
Post by: potul on June 14, 2016, 08:59:19 AM
wow... this looks amazing...

If I only could solder SMD....

Title: Re: Audio Effects DSP Board
Post by: markseel on June 14, 2016, 11:12:22 AM
... Do you think there's any possibility that your board would be compatible with that approach?
See: https://enzienaudio.com/

To some degree yes.  Currently there's a one-to-one mapping from an audio thread to an XMOS computation core which hard-limits thread count to XMOS core count.  You'd have to write code that allocated audio processing objects across these threads to hide the underlying HW architecture.  It's not in my plans but someone could do it I suspect.

... If I only could solder SMD....

I can assemble a few boards for folks interested it using it.  I can make the board design files publicly available - that's a start.  Not sure how to scale this up.
Title: Re: Audio Effects DSP Board
Post by: potul on June 15, 2016, 03:45:06 AM
Mark this is very cool.  As you know, I hate writing DSP code so much I'm willing to write thousands of lines of Java just to avoid it.  :icon_wink:  I recently got a Blackfin DSP eval board, thinking to possibly leverage something like Pure Data through "Heavy" I think it is called, to be able to create more powerful FX than one can accomplish on the FV-1.  Do you think there's any possibility that your board would be compatible with that approach?

See: https://enzienaudio.com/

Regards,

DL

Hi.... I just took a look at this webpage. Did I get it right? Is this framework some kind of "compiler" for PD?

So I can theoretically use some PD projects and convert them to code? interesting.... I have a Raspberry PD project unfinished because the CPU load was too much for the Pi.

Mat
Title: Re: Audio Effects DSP Board
Post by: markseel on June 16, 2016, 10:52:32 PM
The initial code base for building custom audio processing/effects applications is now on GitHub.  It's not been tested much but you can take a look to see how it works :-)  There's not much that you need to do - just add your own DSP code to the audio processing threads.  You'll need to download and install xTIMEcomposer - XMOS tools and source code are free!

Here's some notes:

1) Obtain the framework for building your own apps ...
Code: [Select]
git clone https://github.com/markseel/SimpleDSP.git

2) Set environment path to point to XMOS build tools ...
Code: [Select]
OS X:    /Applications/XMOS_xTIMEcomposer_Community_14.1.1/SetEnv.command
Windows: "c:\Program Files (x86)\XMOS\xTIMEcomposer\Community_14.2.0\SetEnv.bat"

3) Add your own source code to the starter application ...

The main application source code is in "main.c".
See "dsp.h" for DSP support functions.

Code: [Select]
// ================================================================================================
// "main.c"
// ================================================================================================

#include "dsp.h"

// A custom effects processing signal chain is constructed by adding DSP functionality to any of
// the seven audio processing threads below.  Each processing thread is allocated 100 MIPS of the
// total 700 MIPs available and executes once per audio cycle (48 kHz).

// Audio sample data flow is managed by the provided audio processing foundation object code that
// implements USB audio, USB MIDI and serial UART MIDI, the USB/ADC/DAC mixing functions,
// 15-band EQ, and firmware upgrades. Audio flows from through threads 1 through 7 in sequential
// order - all threads are executed once per audio cycle.

// The 'init' functions are each called once at program startup and should be used to initialize
// data used for audio processing.  The 'exec' functions are each called once per audio cycle. Note
// that audio samples are in Q1.31 fixed-point format.

// ------------------------------------------------------------------------------------------------

static void copy_property( int* dst, int idx, const int* src )
{
    int off = 5 * idx;
    dst[0] = src[0+off]; dst[1] = src[1+off]; dst[2] = src[2+off];
    dst[3] = src[3+off]; dst[4] = src[4+off];
}

#define EXAMPLE_PROPERTY_ID1 0x1500
#define EXAMPLE_PROPERTY_ID2 0x1501
#define EXAMPLE_PROPERTY_ID3 0x1502
#define EXAMPLE_PROPERTY_ID4 0x1503

static int example_property_data1[5];
static int example_property_data234[3*5];

void audio_thread_1_init( void )
{
    for( int ii = 0; ii <  5; ++ii ) example_property_data1[ii]   = 0;
    for( int ii = 0; ii < 15; ++ii ) example_property_data234[ii] = 0;
}

void audio_thread_1_exec( int audio_samples[6], int prop_id, const int prop_data[5] )
{
    // Example: Update property with single set of 5 parameters
    if( prop_id == EXAMPLE_PROPERTY_ID1 ) copy_property( example_property_data1, 0, prop_data );

    // Example: Update property with multiple (3) sets of 5 parameters
    if( prop_id >= EXAMPLE_PROPERTY_ID2 && prop_id <= EXAMPLE_PROPERTY_ID4 ) {
        int prop_index = prop_id - EXAMPLE_PROPERTY_ID2;
        copy_property( example_property_data234, prop_index, prop_data );
    }

    // audio_samples[0] contains sample for the left audio channel
    // audio_samples[1] contains sample for the right audio channel
    // other audio samples can be used to pass data to the next audio processing thread

    // Decrease volume by 50% for left and right channels
    audio_samples[0] /= 2; // Left
    audio_samples[1] /= 2; // Right
}

// ------------------------------------------------------------------------------------------------

void audio_thread_2_init( void )
{
}

void audio_thread_2_exec( int audio_samples[6], int prop_id, const int prop_data[5] )
{
    // Do nothing - audio samples are not modified
}

// ------------------------------------------------------------------------------------------------

void audio_thread_3_init( void )
{
}

void audio_thread_3_exec( int audio_samples[6], int prop_id, const int prop_data[5] )
{
    // Do nothing - audio samples are not modified
}

// ------------------------------------------------------------------------------------------------

void audio_thread_4_init( void )
{
}

void audio_thread_4_exec( int audio_samples[6], int prop_id, const int prop_data[5] )
{
    // Do nothing - audio samples are not modified
}

// ------------------------------------------------------------------------------------------------

void audio_thread_5_init( void )
{
}

void audio_thread_5_exec( int audio_samples[6], int prop_id, const int prop_data[5] )
{
    // Do nothing - audio samples are not modified
}

// ------------------------------------------------------------------------------------------------

void audio_thread_6_init( void )
{
}

void audio_thread_6_exec( int audio_samples[6], int prop_id, const int prop_data[5] )
{
    // Do nothing - audio samples are not modified
}

// ------------------------------------------------------------------------------------------------

void audio_thread_7_init( void )
{
}

void audio_thread_7_exec( int audio_samples[6], int prop_id, const int prop_data[5] )
{
}

// ===============================================================================================
// ===============================================================================================

4) Build the application ...
Code: [Select]
OS X:    ./build.sh main
Windows: build.bat main

5) Run the application in RAM using JTAG/XTAG ...

This requires an XTAG-2 or XTAG-3 XMOS JTAG adapter.
Code: [Select]
xrun --xscope main.xe

6) Convert the firmware image to a binary for burning FLASH via UART or USB ...
Code: [Select]
xflash --noinq --boot-partition-size 524288 main.xe -o main.bin

7) Burn firmware binary to FLASH ...
Code: [Select]
Using XTAG:   xflash main.xe
Using USB:    TODO
Using serial: TODO
Title: Re: Audio Effects DSP Board
Post by: markseel on June 19, 2016, 12:24:46 PM
Github repository renamed and added README file:
https://github.com/markseel/FlexFX/blob/master/README.md

First mini FlexFX board should be here this week.
DSP and effects coding examples coming soon!

Open to requests :-)
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on June 20, 2016, 09:42:43 AM
Hi Mark,

This may sound ridiculous, but I'm so cozy with the FV-1 that I want everything else to be just like it.  However some of its features are really handy, e.g.

1) Simple all pass filter for reverbs
2) Inter-sample interpolation on short delay line for flange/chorus
3) Sin/Cos LFO blocks
4) Something like a tanh waveshaper that can be put into a resonant state variable filter block so you can push the resonance into distortion territory while keeping aliasing under control.  FV-1 doesn't actually have a tanh, although there is something similar, I haven't tried it like this (yet).
5) LFSR noise generator

For some reason I am more into building blocks than finished effects!
Title: Re: Audio Effects DSP Board
Post by: markseel on June 20, 2016, 10:30:29 AM
Thanks for the suggestions - not crazy at all - makes sense to have building blocks.  I'll add those to the list for additions to the DSP library.  I'll also add up-sampling and down-sampling (interpolating and decimating FIR's) to support non-linear effects (overdrive, distortion) to help prevent aliasing of the added noise.  The TANH and other similar tables were on my list already - mostly for modeling fuzz/tube/diode transfer functions for distortion effects.  I'll add slew-rate limiting too.  The LFO's should be easy to do.  I already have Lagrange interpolation in the library to support flange/chorus sample interpolation - but I'd suggest that implementors also up/down sampling before/after chorus for the highest quality (assuming that there's enough memory for the higher sample-rate delay line).
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on June 20, 2016, 10:43:04 AM
Lagrange interpolation is really important when you are playing ZZ Top covers! (sorry). I had no idea what it was so I looked it up. 

http://mathworld.wolfram.com/LagrangeInterpolatingPolynomial.html

The FV-1 inter sample interpolation looks like Lagrange interpolation with order=1. Slightly better than nothing.

Can you briefly explain the rationale for up/down sampling for chorus?  Being that I live so much of my life inside the FV-1 which doesn't normally lend itself to oversampling (though I guess it could), my only perception for "why" of over sampling is a) easier filtering out of aliasing components b) better stability of filters when f > fs/4.  But I rarely use filters for guitar effects that go that high. The sweet spot for wah type things is way less than that even at 32 kHz sampling.
Title: Re: Audio Effects DSP Board
Post by: markseel on June 20, 2016, 11:19:22 AM
Good question :)  Largely to reduce the effect of frequency response loss at the higher frequencies as a result of non-ideal interpolation.  Also by 4x up-sampling you gain fractional sub-sampling (at 1x) before applying linear, polynomial, or some other form of interpolation between two samples as determined by an LFO.

Look at the graphs in the literature below and consider the effect of up-sampling, applying polynomial/Lagrange and how it moves the area of significant non-ideal effects of interpolation beyond audible ranges. 

Here's a lot of info on fractional delay lines via interpolation:
https://ccrma.stanford.edu/~jos/Interpolation/Welcome.html
https://ccrma.stanford.edu/~jos/Interpolation/Interpolation.pdf
https://ccrma.stanford.edu/~dattorro/EffectDesignPart2.pdf

I think it's a good idea to try a number of approaches including up/down sampling, polynomial interpolation, and a combo of both and listen to see how they sound.  The polynomial interpolation is low MIPS and low memory.  Up/down sampling requires longish FIR's and increases delay line memory requirements.

Also probably good to consider what the effect is intended to sound like.  If one is trying to recreate a BBD-based effect then perhaps linear interpolation and high-frequency signal loss is a good thing?

Sounds like there's more effects building-block ideas here :D
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on June 20, 2016, 08:50:04 PM
Guy I used to work with was apparently in a band for awhile with Julius Smith (prog, of course).
Title: Re: Audio Effects DSP Board
Post by: markseel on June 22, 2016, 04:57:00 PM
Here's an example of an API for effects components.  You'd put the *_init functions in a thread_X_init function and put the *_run functions in a thread_X_exec function.  The effect parameter updates would happen automatically - you just need to string together these *_run functions in the order that makes sense for your effects.  I'll work up an example next ...


// --------------------------------------------------------------------------------
// Cabinet Simulation
// --------------------------------------------------------------------------------

// Properties for cabsim control (note that there are five 32-bit words per property)

#define PROPERTY_CABSIM_FLAGS       0x1500 // First word is Enable(1)/bypass(0)
#define PROPERTY_CABSIM_DATA_A_NEXT 0x1501 // Used to load block A with IR data
#define PROPERTY_CABSIM_DATA_A_LAST 0x1502 // Used to load block A with IR data
#define PROPERTY_CABSIM_DATA_B_NEXT 0x1503 // Used to load block B with IR data
#define PROPERTY_CABSIM_DATA_B_LAST 0x1504 // Used to load block B with IR data
#define PROPERTY_CABSIM_DATA_C_NEXT 0x1505 // Used to load block C with IR data
#define PROPERTY_CABSIM_DATA_C_LAST 0x1506 // Used to load block C with IR data
#define PROPERTY_CABSIM_DATA_D_NEXT 0x1507 // Used to load block D with IR data
#define PROPERTY_CABSIM_DATA_D_LAST 0x1508 // Used to load block D with IR data
#define PROPERTY_CABSIM_DATA_E_NEXT 0x1509 // Used to load block E with IR data
#define PROPERTY_CABSIM_DATA_E_LAST 0x150A // Used to load block E with IR data

// Initialize cabinet simulator state variables.

void efx_cabsim_lowres1_init( void ); // 1200 sample IR, 25.0 msec
void efx_cabsim_lowres2_init( void ); // 1200 sample IR, 25.0 msec
void efx_cabsim_highres_init( void ); // 3000 sample IR, 62.5 msec

// Execute one pass (one audio cycle) of a tone control.  Note that since the complete
// IR convolution is split accross multiple filters that the 64-bit accumlator must
// be pass between each IR convolution section.
//
// SAMPLE is the input sample.
// ACCUMH is the upper 32-bit word of the 64-bit accumulator.
// ACCUML is the lower 32-bit word of the 64-bit accumulator.
//
// Returns the resulting cabsim sample for the current audio cycle as well as the
// intermediate 64-bit accumulator in order to chain multiple cabsim sub-sections
// (blocks) over some number of threads.

int  efx_cabsim_lowres1_runA( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_lowres1_runB( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_lowres2_runC( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_lowres2_runD( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_highres_runA( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_highres_runB( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_highres_runC( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_highres_runD( int sample_q28, int* accumH, int* accumL );
int  efx_cabsim_highres_runE( int sample_q28, int* accumH, int* accumL );

// Update cabinet simulator parameters

int  efx_cabsimA_update( int property_data[6] );
int  efx_cabsimB_update( int property_data[6] );
int  efx_cabsimC_update( int property_data[6] );
int  efx_cabsimD_update( int property_data[6] );
int  efx_cabsimE_update( int property_data[6] );

// --------------------------------------------------------------------------------
// Tone Control
// --------------------------------------------------------------------------------

// Property for tone controls (note that there are five 32-bit words per property)
//
// Word0 is Enable(1)/bypass(0)
// Word1 is bass level, 0 to 24 (0 = -12dB, 12 = 0dB, 24 = +12dB)
// Word2 is midrange level, 0 to 24 (0 = -12dB, 12 = 0dB, 24 = +12dB)
// Word3 is treble level, 0 to 24 (0 = -12dB, 12 = 0dB, 24 = +12dB)

#define PROPERTY_TONE_1_CONTROL 0x1511
#define PROPERTY_TONE_2_CONTROL 0x1512
#define PROPERTY_TONE_3_CONTROL 0x1513

// Intialize a tone-control object consisting of a 2nd order low-shelving filter
// for bass control, 2nd order peaking for mid, and 2nd order high-shelf for treble.
// The biquad coefficients are pre-computed and placed in a look-up table supporting
// +/- 12dB gain (in 1 dB steps, 25 total steps) for each tone-control band.
//
// FREQ_BASS is the frequency of the low-shelf corner frequency.
// FREQ_MID is the frequency of peaking filter midpoint frequency.
// FREQ_TREB is the frequency of the high-shelf corner frequency.
//
// Frequencies are represented as a fractional value normalized to Fs / 2 (24 kHz)
// 0.0 (0 Hz) > frequency < 1.0 (24 kHz)

void efx_tone1_init( float freq_bass, float freq_mid, float freq_treb  );
void efx_tone2_init( float freq_bass, float freq_mid, float freq_treb  );
void efx_tone3_init( float freq_bass, float freq_mid, float freq_treb  );

// Execute one pass (one audio cycle) of a tone control.
//
// SAMPLE is the input sample.
// Returns the resulting chorus sample for the current audio cycle.

int  efx_tone1_run( int sample_q28 );
int  efx_tone2_run( int sample_q28 );
int  efx_tone3_run( int sample_q28 );

// Update tone control parameters

int  efx_tone1_update( int property_data[6] );
int  efx_tone2_update( int property_data[6] );
int  efx_tone3_update( int property_data[6] );

// --------------------------------------------------------------------------------
// LFO
// --------------------------------------------------------------------------------

// Property for LFO control (note that there are five 32-bit words per property)
//
// Word0 is is the oscillator frequency - a fractional value normalized to Fs / 2 (24 kHz)

#define PROPERTY_LFO_1_CONTROL 0x1521
#define PROPERTY_LFO_1_CONTROL 0x1522
#define PROPERTY_LFO_1_CONTROL 0x1523

// Intialize an LFO object.

void efx_lfo1_init( void );
void efx_lfo2_init( void );
void efx_lfo3_init( void );

// Execute one pass (one audio cycle) of an LFO.  Must be called once per audio cycle.
// Function returns the LFO magnitude; Q28(0.0 <= MAGNITUDE < Q28(1.0)

int  efx_lfo1_run( void );
int  efx_lfo2_run( void );
int  efx_lfo3_run( void );

// Update LFO parameters

int  efx_lfo1_update( int property_data[6] );
int  efx_lfo2_update( int property_data[6] );
int  efx_lfo3_update( int property_data[6] );

// --------------------------------------------------------------------------------
// Chorus
// --------------------------------------------------------------------------------

// Property for chorus control (note that there are five 32-bit words per property)
//
// Word0 is the type; 0 for sine wave, 1 for triangle
// Word1 is is the oscillator period in number-of-samples (at 48 kHz)

#define PROPERTY_CHORUS_CONTROL 0x1530

// Word0 is chorus 1 enable(=1) or bypass (=0)
// Word1 is chorus 2 enable(=1) or bypass (=0)
// Word2 is chorus 3 enable(=1) or bypass (=0)

#define PROPERTY_CHORUS_1_PARAMS 0x1531
#define PROPERTY_CHORUS_2_PARAMS 0x1532
#define PROPERTY_CHORUS_3_PARAMS 0x1533

// Word0 is chorus sub-sampling interpolation type
// ---> 0 for none, 1 for linear, 2 for 2nd order Lagrange, 3 for 3rd order Lagrange
// Word1 is base delay in number of samples
// Word2 is the modulation depth in number of samples
// Word3 (Q28 format) is the wet/dry mix; dry=Q28(0.0), 50%=Q28(0.5), wet=Q28(0.999...).

// Initialize a chorus object.
//
// LFO number refers to LFO object (1, 2 or 3).
// INTERP_TYPE = 0 for linear, 1 for 2nd order Lagrange, 2 for 3rd order Lagrange.
// DELAY_LINE points to sample delay line of lenth 2^N.  Make sure it's long enough!

void efx_chorus1_init( int* delay_line );
void efx_chorus2_init( int* delay_line );
void efx_chorus3_init( int* delay_line );

// Execute one pass (one audio cycle) of a chorus.
//
// SAMPLE is the input sample,
// Returns the resulting chorus sample for the current audio cycle.

int  efx_chorus1_run( int sample_q28 )
int  efx_chorus2_run( int sample_q28 )
int  efx_chorus3_run( int sample_q28 )

// Update chorus parameters

int  efx_chorus1_update( int property_data[6] );
int  efx_chorus2_update( int property_data[6] );
int  efx_chorus3_update( int property_data[6] );

// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
Title: Re: Audio Effects DSP Board
Post by: free electron on June 23, 2016, 03:44:39 AM
Hi Mark,
do you plan to release the schematic for those who'd prefer to design their own PCB? I wanted to build a good quality stereo speaker simulator for my mini looping pedalboard. Your project looks perfect for that.
Do you know what range of current consumption is to be expected?
Title: Re: Audio Effects DSP Board
Post by: markseel on June 23, 2016, 10:43:24 AM
I'll post the schematic so you can build your own PCB or make modifications.  I haven't measured power consumption yet but if the XMOS part is working hard I'd expect this board to draw a lot of power - perhaps 200mA to 250mA at 5V.
Title: Re: Audio Effects DSP Board
Post by: markseel on June 23, 2016, 12:11:56 PM
Here's an example for using some effects components showing an LFO and a chorus followed by a tone control for channel 0 (Left channel).  They're all put in thread2 just for illustration but you can be put effects in any thread of course as long as the signal flow makes sense (audio flows through threads 1 through 7.

This example would use just a fraction of the 100 MIPs available to the thread and there's a total of seven threads (each at 100 MIPs) - so there's a lot of processing power available.  It's not out of the question to implement a complex effects chain (compression, overdrive(s), flanging/chrous, tone/eq, cab sim) on one board.

The 'audio_thread_N_init' gets called once at board power-up or after a reset.  The 'audio_thread_N_exec' gets called once every audio cycle with up to four audio channels and property data being supplied every cycle.  By default 'audio_samples[0]' and 'audio_samples[1]' represent left and right audio channels respectively.  By having up to four audio channels passed from thread to thread one could represent a single audio channel (left or right) at up to 4x up-sampling - good for non-linear effects like distortion (more on that later).

The property data is supplied automatically and sourced via USB MIDI or serial/UART MIDI.  'property_data[0]' is the property ID which is zero when no property is being updated and non-zero when a property is to be updated.  The effects components will use the data automatically (by calling the effect property update function) if the property ID applies to a particular effect (see code below).  The remaining five words in the property_data[6] array represent the five 32-bit words that comprise a property parameter set.


void audio_thread_2_init( void )
{
    // Initialize any effects used in this thread (thread #2)

    efx_lfo1_init();
    efx_chorus1_init();

    // Bass frequency = 0.00208333 * Fs/2  ---> 100.0  Hz for Fs = 48 kHz
    // Mid frequency = 0.0208333 * Fs/2    ---> 1.000 kHz for Fs = 48 kHz
    // Treble frequency = 0.0208333 * Fs/2 ---> 10.00 kHz for Fs = 48 kHz
    efx_tone1_init( 0.00208333, 0.0208333, 0.208333 );
}

void audio_thread_2_exec( int audio_samples[4], const int property_data[6] )
{
    // Process the left channel audio sample for the current audio cycle.
    // The right channel (audio_samples[1]) and the other two audio channels are not modified.

    efx_lfo1_run(); // Update LFO value
    sample[0] = efx_chorus1_run( sample[0] ); // Apply tone shaping to left audio channel
    sample[0] = efx_tone1_run  ( sample[0] ); // Apply chorus effect to left audio channel

    // Give effects objects an opportunity to update parameters if property data applies

    efx_lfo1_update   ( property_data );
    efx_chorus1_update( property_data );
    efx_tone1_update  ( property_data );
}
Title: Re: Audio Effects DSP Board
Post by: potul on June 24, 2016, 05:30:04 AM
So, where do you provide the LFO and chorus parameters (lfo freq, chorus depth, etc...? in the property_data array?
Title: Re: Audio Effects DSP Board
Post by: markseel on June 24, 2016, 10:30:59 AM
So, where do you provide the LFO and chorus parameters (lfo freq, chorus depth, etc...? in the property_data array?

Yes - in the property data.  The property data is filled in and passed to the audio processing threads automatically (as they arrive from a USB or serial MIDI source) but you can force an update yourself this way:

void audio_thread_2_exec( int audio_samples[4], const int property_data[6] )
{
    // Process the left channel audio sample for the current audio cycle.
    // The right channel (audio_samples[1]) and the other two audio channels are not modified.

    efx_lfo1_run(); // Update LFO value
    sample[0] = efx_chorus1_run( sample[0] ); // Apply tone shaping to left audio channel
    sample[0] = efx_tone1_run( sample[0] ); // Apply chorus effect to left audio channel

    // Manually update LFO parameters ...
    property_data[0] = PROPERTY_LFO_1_CONTROL;
    property_data[1] = Q28( 0.00016667 ); // 4 Hz --> (4 / (Fs/2)) 
    efx_lfo1_update( property_data );

    // Manually update chorus parameters ...
    property_data[0] = PROPERTY_CHORUS_1_CONTROL;
    property_data[1] = 960; // Base delay in number of samples --> 20 msec
    property_data[2] = 192; // Modulation depth in number of samples --> 4 msec
    property_data[3] = Q28(+0.5); // wet/dry mix --> 50%
    efx_chorus1_update( property_data );

    // Manually update tone control parameters ...
    property_data[0] = PROPERTY_TONE_1_CONTROL;
    property_data[1] = Q28(0.00416667); // Bass (low-shelf corner frequency) is 100 Hz --> 100 / (Fs/2)
    property_data[2] = Q28(0.04166667); // Mid (peaking center frequency) is 1000 Hz --> 1000 / (Fs/2)
    property_data[3] = Q28(0.41666667); // Treble (hi-shelf corner frequency) is 10000 Hz --> 10000 / (Fs/2)
    efx_tone1_update( property_data );
}
Title: Re: Audio Effects DSP Board
Post by: micromegas on June 24, 2016, 02:41:26 PM
I may be asking something someone asked before, but... are you going to sell these? If that's the case, I would love to get one. I've been wanting to try the XMOS family for quite long
Title: Re: Audio Effects DSP Board
Post by: markseel on June 24, 2016, 03:56:37 PM
Yes, I want to get these boards out to folks but I'm not sure how to do that yet.  Making them one-by-one is a bit of a pain :o  I'll try to make a few here and there and sell in small quantities until I can get a small production run figured out.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on June 25, 2016, 10:42:29 AM
Hi Mark,

I am thinking about how SpinCAD could be adapted to this platform.  At the highest level, there is an idea of representing DSP functional blocks with input and output connections, both audio control, and popup control panels to set static aspects of that block (e.g. maximum delay time).  For the FV-1 it's straightforward because there's only one "thread" so to speak, and I can easily connect something at the beginning of the chain to the very end (for example, "dry" mix).

You have described the Xmos system as working on a number of separate threads which get executed in order (I think).  So my question is, how would I go about passing a signal from the first block (ADC input) to very nearly the final block (wet/dry mix prior to DAC)?

DL
Title: Re: Audio Effects DSP Board
Post by: markseel on June 25, 2016, 11:22:11 AM
Moving samples from one thread to another is handled automatically by the provided framework.  The code in each thread then is only concerned with DSP and not with moving audio data around.

The basic model is that seven threads all work at the same time on different samples to form a data-flow pipleline.


ADC--->(Sample N)--->Thread1--->(Sample N-1)...--->(Sample N-7)--->Thread7--->(Sample N-8)--->DAC


With seven cores/threads there's seven samples (or more specifically sets of samples representing left,
right and two auxillary channels) ordered in time being worked on simultaneously.

The sample from the ADC is sent to thread1, thread1 output is sent to thread2 input, ...
thread6 output is sent to thread7, thread7 output is sent to the DAC.  This complete cycle
occurs once *every* audio cycle (at 48 kHz).

This is how we achieve such high DSP bandwidth; by operating seven 100 MIPs cores/threads
all at the same time but working on it's own sample in the dataflow.


Audio   |   Sample number being processed in each thread ...
Cycle   |   ADC       Thread1   Thread2    ...   Thread6   Thread7   DAC
--------+-------------------------------------------------------------------
N+0     |   N+0       -         -                -         -         -   
N+1     |   N+1       N+0       -                -         -         -
N+2     |   N+2       N+1       N+0              -         -         -
N+3     |   N+3       N+2       N+1              -         -         -
...     |
N+8     |   N+8       N+7       N+6              N+2       N+1       N+0
N+9     |   N+9       N+8       N+7              N+3       N+2       N+1

Title: Re: Audio Effects DSP Board
Post by: Digital Larry on June 25, 2016, 11:52:14 AM
If I catch your drift then, ADC input could be passed through the other blocks and arrive at the last core 7 or 8 sample ticks later?
Title: Re: Audio Effects DSP Board
Post by: markseel on June 25, 2016, 04:58:16 PM
That's right, with that illustration there would be a minimum 8 sample delay from ADC to DAC.  But keep in mind that the samples that go in to thread 1 and that come out of thread 7 are actually routed as follows where the seven threads we're talking about comprise the [effects] block below:


[Guitar (ADC)]-----+-------------------------[Mixer2]---->[USB In]
                   |                            /\
                   |                            |
                   \/                           |
                [Mixer1]--->[Effects]--->[Spatialization]
                   /\                           |
                   |                            |
               (Left Ch.)       +---------------+
                   |            |
                   |            \/
[USB Out]----------+-------->[Mixer3]--->[GraphicEQ]--->[Volume]--->[Line Out (DAC)]


So total delay from ADC to DAC is eight sample periods (less than 0.167 milliseconds with Fs = 48 kHz) for the [effects] plus the group delay through the AK4556 ADC and DAC (17+21 samples or 0.8 milliseconds) plus any other delays added by [Mixer1], [Spatialization], [Mixer3], and [GraphicEQ] blocks that are part of the framework and therefore in the audio path by default.  Total delay then for this effects framework is less than 1 msec.

Here's an idea.  I could also offer a more minimal framework that omits the mixers, eq and spatialization DSP code.  That would then look like this:

[Guitar (ADC)]-----+       +---->[Line Out (DAC)]
                   |       |
                   |       |
                  \/       |
              [Effects]----+
                  /\       |   
                   |       | 
                   |       |
[USB Out]----------+       +---->[USB In]


Notice from the previous code sample (earlier post) that the four samples passed in to and out of the function (for every audio cycle).  With this simpler default audio path definition the audio processing thread function arguments would then be defined as as ADC/DAC left, ADC/DAC right, USB out/in left, USB out/in right allowing you to mix any time (in any thread) as you see fit.  So using the example code for the LFO, Chorus and Tone control from a few postings ago ... see the comments below that call out the meaning of the four audio samples pass in/out.

// audio_sample[0] is left channel ADC (incoming) sample and left channel DAC (outgoing) sample
// audio_sample[1] is right channel ADC (incoming) sample and right channel DAC (outgoing) sample
// audio_sample[2] is left channel USB (incoming) sample and left channel USB (outgoing) sample
// audio_sample[3] is right channel USB (incoming) sample and right channel USB (outgoing) sample

void audio_thread_2_exec( int audio_samples[4], const int property_data[6] )
{
    // Process the ADC/DAC left channel audio sample for the current audio cycle.
    // The right ADC/DAC channel and USB audio channels are not modified.

    efx_lfo1_run(); // Update LFO value
    sample[0] = efx_chorus1_run( sample[0] ); // Apply tone shaping to left audio channel
    sample[0] = efx_tone1_run  ( sample[0] ); // Apply chorus effect to left audio channel

    // Give effects objects an opportunity to update parameters if property data applies

    efx_lfo1_update   ( property_data );
    efx_chorus1_update( property_data );
    efx_tone1_update  ( property_data );
}
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 13, 2016, 09:54:51 PM
Mark, How many all pass filters would that thing hold do you think?  I have an application that seems to want a couple hundred.

DL
Title: Re: Audio Effects DSP Board
Post by: micromegas on July 14, 2016, 06:38:58 AM
Mark, How many all pass filters would that thing hold do you think?  I have an application that seems to want a couple hundred.

DL
Spectral delay?  :icon_biggrin:
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 15, 2016, 11:23:44 AM
cyletax!
Title: Re: Audio Effects DSP Board
Post by: micromegas on July 15, 2016, 01:01:12 PM
cyletax!
I need to give a try to that kind of implementation. Tried to code a plugin on JUCE using the fftw3 but the way it works gave me more than a headache and the project ended up in the bin...
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 16, 2016, 12:51:31 AM
Here is a really wild sounding spectral delay implemented in Pure Data.  I ran it on my PC.

https://guitarextended.wordpress.com/2012/02/07/spectral-delay-effect-for-guitar-with-pure-data/
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 16, 2016, 10:17:14 PM
Hi Mark,

I'm trying to get going on Ubuntu Linux, following Mac instructions.

Code: [Select]
gary@gary-Latitude-E6420:~/SimpleFX/FlexFX$ ./build.sh main
xcc: dsp.c: No such file or directory
xcc: flexfx.xc.o: No such file or directory
gary@gary-Latitude-E6420:~/SimpleFX/FlexFX$ ls *.c
main.c

Missing a few files apparently.  As I have something that I can't currently accomplish on an FV-1 I really want to give this a look ASAP.

Thanks,

Gary
er, I mean Larry   ::)
Title: Re: Audio Effects DSP Board
Post by: micromegas on July 18, 2016, 07:35:39 AM
Here is a really wild sounding spectral delay implemented in Pure Data.  I ran it on my PC.

https://guitarextended.wordpress.com/2012/02/07/spectral-delay-effect-for-guitar-with-pure-data/

That's the one I tried to base my plugin on! The interface is nice but not so easy to control and I was trying to accomplish something more intuitive. The fftw3 got in the way and I was running out of time so ended up coding a multiband-multitap delay.
Title: Re: Audio Effects DSP Board
Post by: markseel on July 18, 2016, 12:40:02 PM
Hi 'Larry' -

I'm trying to get going on Ubuntu Linux, following Mac instructions.

Doesn't look like the environment variables are set.  Did you execute the 'SetEnv.command' script in the XMOS installation directory?

Mark, How many all pass filters would that thing hold do you think?  I have an application that seems to want a couple hundred.

For a first order allpass of perhaps y[n] = a*y[n-1] + x[n-1] - a*x[n] we'd have two MAC's and an ADD per sample.  We can execute 500 to 600 FIR taps per core (one MAC and one delay line update) so dividing that figure by two or three might be a good first estimate.  That puts us at about 200 1st order all-pass filters per core.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 18, 2016, 12:52:46 PM
Folders are a bit different than you showed, but:

Code: [Select]
gary@gary-Latitude-E6420:~/SimpleFX/FlexFX$ source ~/XMOS/xTIMEcomposer/Community_14.2.0/SetEnv
gary@gary-Latitude-E6420:~/SimpleFX/FlexFX$ ./build.sh main
xcc: dsp.c: No such file or directory
xcc: flexfx.xc.o: No such file or directory
gary@gary-Latitude-E6420:~/SimpleFX/FlexFX$ ls
build.bat              uac2_bulk.xc.o          xud_io_loop.s.o
build.sh               uac2_control.xc.o       xud_manager.xc.o
core_dsp.c.o           uac2_device.xc.o        xud_phy_reset_user.xc.o
core_peripherals.xc.o  uac2_dfu.xc.o           xud_ports.xc.o
core_system.xc.o       uac2_main.xc.o          xud_power_sig.xc.o
dsp.h                  uac2_midi.xc.o          xud_set_crc_table_addr.c.o
lib_assert.xc.o        xud_client.xc.o         xud_set_dev_addr.xc.o
lib_gpio.xc.o          xud_crc5_table.s.o      xud_setup_chan_override.s.o
License.md             xud_device_attach.xc.o  xud_support.xc.o
main.c                 xud_ep_funcs.s.o        xud_test_mode.xc.o
main.xn                xud_ep_functions.xc.o   xud_uifm_pconfig.s.o
README.md              xud_get_done.c.o        xud_uifm_reg_access.s.o
uac2_audio.xc.o        xud_glx.xc.o            xud_user.c.o
uac2_buffers.c.o       xud_io_loop_call.xc.o


200 all-passes per core sounds pretty promising!
Title: Re: Audio Effects DSP Board
Post by: markseel on July 18, 2016, 01:40:21 PM
Oh OK.  My bad.  Edit 'build.sh' and remove 'dsp.c' from the list of files to compile/link.
Title: Re: Audio Effects DSP Board
Post by: markseel on July 18, 2016, 01:44:03 PM
I should add DSP library code for all passes then.  Cascaded all-passes would be good to have, true?  This would help to minimize error since the sections would be cascaded (internal to the library) such that the 64-bit accumulator is maintained for each section rather than being truncated to 32-bit after a single section.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 18, 2016, 02:17:07 PM
Cascaded all passes would be awesome.  Keep in mind (maybe it's obvious) that I would be using "stretched" all passes, namely width more than one memory element, and in the ideal case, they'd be dynamically adjustable with inter sample interpolation.  At your convenince of course.   :icon_smile:
Title: Re: Audio Effects DSP Board
Post by: markseel on July 18, 2016, 02:26:15 PM
I'm not familiar with those but I'm sure I could code them up after some reading.  Have a good link or two on how they work?  This looks good: http://dafx09.como.polimi.it/proceedings/papers/paper_36.pdf
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 18, 2016, 03:20:50 PM
Exactly what I had in mind!   8)

It's like the all pass stages used in FV-1 reverbs.

Still missing:

flexfx.xc.o

I tried removing the reference in build.sh and wound up with a ton of Undefined References,

Thx,

DL

Title: Re: Audio Effects DSP Board
Post by: markseel on July 18, 2016, 03:27:47 PM
OK - it was missing.  Updated GiTHub.  You should pull down all files just in case.
https://github.com/markseel/FlexFX.git
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 18, 2016, 05:39:23 PM
Getting closer.  I presume the following indicates that Nirvana is just around the next bend.

Code: [Select]
gary@gary-Latitude-E6420:~/SimpleFX/FlexFX$ ./build.sh main
xmap: Warning: More than 6 cores used on a tile. Ensure this is not the case on tile running XUD.
Constraint check for tile[0]:
  Cores available:            8,   used:          7 .  OKAY
  Timers available:          10,   used:          9 .  OKAY
  Chanends available:        32,   used:         31 .  OKAY
  Memory available:       262144,   used:      56284 .  OKAY
    (Stack: 3132, Code: 28084, Data: 25068)
Constraints checks PASSED.
Constraint check for tile[1]:
  Cores available:            8,   used:          5 .  OKAY
  Timers available:          10,   used:          5 .  OKAY
  Chanends available:        32,   used:         10 .  OKAY
  Memory available:       262144,   used:       4984 .  OKAY
    (Stack: 764, Code: 3640, Data: 580)
Constraints checks PASSED.
gary@gary-Latitude-E6420:~/SimpleFX/FlexFX$

Don't have any hardware yet but I like the looks of it so far.
Title: Re: Audio Effects DSP Board
Post by: markseel on July 18, 2016, 07:11:34 PM
Yes!  You're ready to rock.

The 'core_dsp.h' has low level DSP support.  I'll be creating an additional library with higher level DSP support - like for the all pass filters, EQ's, cab sims, overdrive/distortion/gain blocks, etc.  Also need to add comments, documentation, and code to illustrate how to use the framework and how to make effects.  This will take some time :-)

The latest board works so the last round of prototype boards will be made.  These will be used to demo the system and to send to various folks for evaluation and experimentation.  I'll send you one - should be in a few weeks.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 18, 2016, 08:56:59 PM
Thx Mark!
Title: Re: Audio Effects DSP Board
Post by: markseel on July 19, 2016, 10:54:11 AM
Here's a cabinet simulator for up to 50 msec of impulse response processing.  The IR data can be loaded/modified via MIDI.  Not tested yet - just for illustration for now to show how to use the framework.  Actual code can be obtained from GitHub.

To build: ./build.sh cabsim

Code: [Select]
// ================================================================================================
// "cabsim.c"
// ================================================================================================
//
// A custom effects processing signal chain is constructed by adding DSP functionality to any of
// the seven audio processing threads below.  Each processing thread is allocated 100 MIPS of the
// total 500 MIPs available and executes once per audio cycle (48 kHz).
//
// Audio sample data flow is managed by the provided audio processing foundation object code that
// implements USB audio, USB MIDI and serial UART MIDI, and firmware upgrades. Audio flows from
// threads 1 through 7 in sequential order - all threads are executed once per audio cycle.
//
// The 'init' functions are each called once at program startup and should be used to initialize
// data used for audio processing.  The 'exec' functions are each called once per audio cycle. Note
// that audio samples are in Q1.31 fixed-point format (one sign bit, 31 fractional bits).
//
// Each 'exec' function accepts 'samples[8]' and 'property[6]' as arguments.
//
// The 'samples' array contains 8 input samples upon function entry and represent the 8 output
// samples on function exit.  If no values in the 'samples' array are modified then the audio data
// is passed through the thread on to the next thread unmodified.  Each value in the samples array
// represents:
//
// For thread 1 (the first processing block in the audio processing chain):
//   Sample[0] is the ADC audio from the instrument (left channel)
//   Sample[1] is the ADC audio from the instrument (right channel)
//   Sample[2] is the USB audio output from the USB host (left channel)
//   Sample[3] is the USB audio output from the USB host (right channel)
//   Sample[4,5,6,7] are user defined and be used to pass other data from thread 1 to thread 2
//
// For threads 2,3,4:
//   Sample[4,5,6,7] are user defined and can be used to pass additional samples or data from
//   threads 2,3 to threads 3,4 respectively.  Note that the FlexFX audio framework only makes
//   assumptions of sample mappings to/from USB/ADC/DAC audio channels in threads 1 and 5.
//
// For thread 5 (the last processing block in the audio processing chain):
//   Sample[0] is the DAC audio to the monitor or amplifier (left channel)
//   Sample[1] is the DAC audio to the monitor or amplifier (right channel)
//   Sample[2] is the USB audio input to the USB host (left channel)
//   Sample[3] is the USB audio input to the USB host (right channel)
// ------------------------------------------------------------------------------------------------

#include "core_types.h"
#include "core_dsp.h"

#define PROPERTY_CABSIM_PARAMS 0x1400 // First word is enable / disable (bypass)
#define PROPERTY_CABSIM_SET_A  0x1401
#define PROPERTY_CABSIM_SET_B  0x1402
#define PROPERTY_CABSIM_SET_C  0x1403
#define PROPERTY_CABSIM_SET_D  0x1404
#define PROPERTY_CABSIM_SET_E  0x1405

int cabsimA_coeff[480], cabsimA_state[480];
int cabsimB_coeff[480], cabsimB_state[480];
int cabsimC_coeff[480], cabsimC_state[480];
int cabsimD_coeff[480], cabsimD_state[480];
int cabsimE_coeff[480], cabsimE_state[480];

void _copy_property( int* dst, int index, const int* src )
{
    dst += 5 * index;
    dst[0] = src[1]; dst[1] = src[2]; dst[2] = src[3];
    dst[3] = src[4]; dst[4] = src[5];
}

// ------------------------------------------------------------------------------------------------

void audio_thread_1_init( void )
{
    for( int ii = 0; ii < 480; ++ii ) cabsimA_coeff[ii] = cabsimA_state[ii] = 0;
    cabsimA_coeff[0] = Q31(+0.199);
}

void audio_thread_1_exec( int samples[8], const int property[6] )
{
    static int index = 0, enabled = false;

    // Check to see if property is being updated. Each time the incoming property ID (property[0])
    // matches our CabSim IR data property ID then copy the property data (property[1-5] and then
    // increment the index into the cab sim data array so that successive properties with repated
    // property ID's can be used to load all cab sim data.

    if( property[0] == PROPERTY_CABSIM_SET_A && index < 96 )
    {
        _copy_property( cabsimA_coeff, index++, property+1 );
    }
    else index = 0;

    // Check for cab sim parameters (first word of the five is the enable/disable flag).
    if( property[0] == PROPERTY_CABSIM_PARAMS ) enabled = property[1];

    if( !enabled ) return; // Leave sample[0] unmodified

    int *cc = cabsimA_coeff, *ss = cabsimA_state;

    dsp_fir_preamble( samples[2], 31 ); // Start with instrument input (ADC) left channel

    ... repeat this set or macros below 20 times (left out here for brevity)
    ... dsp_fir_body( 0 ); dsp_fir_body( 1 ); dsp_fir_body( 2 );
    ... dsp_fir_body( 3 ); dsp_fir_body( 4 ); dsp_fir_body( 5 );
    ... cc += 24; ss += 24;

    // Pass the instrument (left channel) sample to the next stage in case the cabsim is disabled
    // Instrument (right) and both USB channels are unmodified
    // Pass intermediate FIR 64-bit accumulator words for the next FIR stage
 
    samples[0] = s0; samples[4] = ah; samples[5] = al;
}

// ------------------------------------------------------------------------------------------------

void audio_thread_2_init( void )
{
    for( int ii = 0; ii < 480; ++ii ) cabsimB_coeff[ii] = cabsimB_state[ii] = 0;
}

void audio_thread_2_exec( int samples[8], const int property[6] )
{
    static int index = 0, enabled = false;

    if( property[0] == PROPERTY_CABSIM_SET_B && index < 96 )
    {
        _copy_property( cabsimB_coeff, index++, property+1 );
    }
    else index = 0;

    // Check for cab sim parameters (first word of the five is the enable/disable flag).
    if( property[0] == PROPERTY_CABSIM_PARAMS ) enabled = property[1];

    if( !enabled ) return; // Leave sample[0] unmodified

    int *cc = cabsimB_coeff, *ss = cabsimB_state;

    // Resume the FIR using instrument left channel and the 64-bit accumulator words
    dsp_fir_continue( samples[0], samples[4], samples[5] );
   
    ... repeat this set or macros below 20 times (left out here for brevity)
    ... dsp_fir_body( 0 ); dsp_fir_body( 1 ); dsp_fir_body( 2 );
    ... dsp_fir_body( 3 ); dsp_fir_body( 4 ); dsp_fir_body( 5 );
    ... cc += 24; ss += 24;

    // Pass the instrument (left channel) sample to the next stage in case the cabsim is disabled
    // Instrument (right) and both USB channels are unmodified
    // Pass intermediate FIR 64-bit accumulator words for the next FIR stage

    samples[0] = s0; samples[4] = ah; samples[5] = al;
}

// ------------------------------------------------------------------------------------------------

void audio_thread_3_init( void )
{
    for( int ii = 0; ii < 480; ++ii ) cabsimC_coeff[ii] = cabsimC_state[ii] = 0;
}

void audio_thread_3_exec( int samples[8], const int property[6] )
{
    static int index = 0, enabled = false;

    if( property[0] == PROPERTY_CABSIM_SET_C && index < 96 )
    {
        _copy_property( cabsimC_coeff, index++, property+1 );
    }
    else index = 0;

    // Check for cab sim parameters (first word of the five is the enable/disable flag).
    if( property[0] == PROPERTY_CABSIM_PARAMS ) enabled = property[1];

    if( !enabled ) return; // Leave sample[0] unmodified

    int *cc = cabsimC_coeff, *ss = cabsimC_state;

    // Resume the FIR using instrument left channel and the 64-bit accumulator words
    dsp_fir_continue( samples[0], samples[4], samples[5] );
   
    ... repeat this set or macros below 20 times (left out here for brevity)
    ... dsp_fir_body( 0 ); dsp_fir_body( 1 ); dsp_fir_body( 2 );
    ... dsp_fir_body( 3 ); dsp_fir_body( 4 ); dsp_fir_body( 5 );
    ... cc += 24; ss += 24;

    // Pass the instrument (left channel) sample to the next stage in case the cabsim is disabled
    // Instrument (right) and both USB channels are unmodified
    // Pass intermediate FIR 64-bit accumulator words for the next FIR stage

    samples[0] = s0; samples[4] = ah; samples[5] = al;
}

// ------------------------------------------------------------------------------------------------

void audio_thread_4_init( void )
{
    for( int ii = 0; ii < 480; ++ii ) cabsimD_coeff[ii] = cabsimD_state[ii] = 0;
}

void audio_thread_4_exec( int samples[8], const int property[6] )
{
    static int index = 0, enabled = false;

    if( property[0] == PROPERTY_CABSIM_SET_D && index < 96 )
    {
        _copy_property( cabsimD_coeff, index++, property+1 );
    }
    else index = 0;

    // Check for cab sim parameters (first word of the five is the enable/disable flag).
    if( property[0] == PROPERTY_CABSIM_PARAMS ) enabled = property[1];

    if( !enabled ) return; // Leave sample[0] unmodified

    int *cc = cabsimD_coeff, *ss = cabsimD_state;

    // Resume the FIR using instrument left channel and the 64-bit accumulator words
    dsp_fir_continue( samples[0], samples[4], samples[5] );

    ... repeat this set or macros below 20 times (left out here for brevity)
    ... dsp_fir_body( 0 ); dsp_fir_body( 1 ); dsp_fir_body( 2 );
    ... dsp_fir_body( 3 ); dsp_fir_body( 4 ); dsp_fir_body( 5 );
    ... cc += 24; ss += 24;

    // Pass the instrument (left channel) sample to the next stage in case the cabsim is disabled
    // Instrument (right) and both USB channels are unmodified
    // Pass intermediate FIR 64-bit accumulator words for the next FIR stage

    samples[0] = s0; samples[4] = ah; samples[5] = al;
}

// ------------------------------------------------------------------------------------------------

void audio_thread_5_init( void )
{
    for( int ii = 0; ii < 480; ++ii ) cabsimE_coeff[ii] = cabsimE_state[ii] = 0;
}

void audio_thread_5_exec( int samples[8], const int property[6] )
{
    static int index = 0, enabled = false;

    if( property[0] == PROPERTY_CABSIM_SET_E && index < 96 )
    {
        _copy_property( cabsimE_coeff, index++, property+1 );
    }
    else index = 0;

    // Check for cab sim parameters (first word of the five is the enable/disable flag).
    if( property[0] == PROPERTY_CABSIM_PARAMS ) enabled = property[1];

    if( !enabled ) return; // Leave sample[0] unmodified

    int *cc = cabsimE_coeff, *ss = cabsimE_state;
 
    // Resume the FIR using instrument left channel and the 64-bit accumulator words
   dsp_fir_continue( samples[0], samples[4], samples[5] );
   
    ... repeat this set or macros below 20 times (left out here for brevity)
    ... dsp_fir_body( 0 ); dsp_fir_body( 1 ); dsp_fir_body( 2 );
    ... dsp_fir_body( 3 ); dsp_fir_body( 4 ); dsp_fir_body( 5 );
    ... cc += 24; ss += 24;

    // Pass the instrument left channel sample (when cabsim is disabled/bypassed) ...
    // ... or the FIR result as left instrument channel (cabsim is enabled)
 
    dsp_fir_postamble( samples[0], 31 );
}

// ===============================================================================================
// ===============================================================================================
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on July 19, 2016, 11:41:13 AM
Mark this is awesome.  A little hard to absorb without doing it hands-on but looking forward to that also.  One thing I'm going to be interested in accomplishing will be to pass output of downstream cores back to previous ones e.g. for delay feedback loops with lots of processing in between.  So the aspect of a several sample time delay will not matter.

Thx,

DL
Title: Re: Audio Effects DSP Board
Post by: wizzgmb on August 29, 2016, 11:40:17 AM
would really like to get one of these to play with
Title: Re: Audio Effects DSP Board
Post by: Transmogrifox on August 29, 2016, 01:49:46 PM
Just noticed this thread...guess it slipped past me.  Looks really interesting.  My current challenge is finding a "stompboxable" hardware platform for guitar effects that doesn't incur the cost of a $500+ dev board of some DSP device.  Having something where I can just start writing DSP code without doing board design, slog through writing drivers for an audio interface, getting basic DSP I/O boring stuff done....  :D

I am also looking at Bela, but this adds another possibility to the mix.

Good question :)  Largely to reduce the effect of frequency response loss at the higher frequencies as a result of non-ideal interpolation.  Also by 4x up-sampling you gain fractional sub-sampling (at 1x) before applying linear, polynomial, or some other form of interpolation between two samples as determined by an LFO.

On fractional delay interpolation, here is one approach:  http://cackleberrypines.net/transmogrifox/src/rpi/delay_line_fx/ (http://cackleberrypines.net/transmogrifox/src/rpi/delay_line_fx/)  (look at flange.c and equal importance is lfo.c)

I started by considering BBD flangers and chorus effects:  They use a 3rd order anti-aliasing filter at around 6 kHz to 8 kHz cut-off going in, and about the same coming out used as the reconstruction filter.

I was considering up-sampling, but when I got to thinking about the operations in upsampling, I realized that running an 8th-order filter with significant rejection by the time it gets to fs/4 (using 48 kHz), then linear interpolation following the biquad section is essentially equivalent to upsampling, interpolating, then downsampling.

The trade-off?  Bandwidth. 
Is this a problem?  No.

In fact this is probably part of the effect with a BBD chorus or flanger (especially with a flanger where the regen control results in reduced bandwidth with each regen cycle).

The second thing I explored in the code linked is the LFO.  What does it take to make a triangle wave pitch change?  The integral of the tri-wave.  The brute-force way to this is to compute the math directly, but I set up my LFO to compute the "twiddle factors" once upon LFO initialization (and parameter change) then it just keeps a running sum of a triangle oscillator -- only requires addition so it's lower CPU usage than computing X^2 and sqrt() functions.

The resulting LFO is sinusoid-ish so it could be used with fairly pleasant results in a tremolo and probably would be nice sounding in a phaser.

This other code includes a sine wave LFO computed also with CPU usage comparable to a single biquad filter (it's derived from the state-variable biquad filter):

Code: [Select]
//Setup in initialization
     lfoConst =  2.0*M_PI*lfoRate / fS;
     sinPart = 1.0;
     cosPart = 0.0;

Code: [Select]
        //run LFO during each sample period
        sinPart += lfoConst*cosPart;
        cosPart -= sinPart*lfoConst;

Maybe this is useful to somebody.  The flanger code includes envelope control for every parameter so it's possible to do some really interesting things with this as a basic building block. 

I found that higher order Lagrange interpolators don't seem to make much *audible* difference over the basic linear interpolator for guitar fx.  For rapid LFO changes either bandwidth-limiting or upsampling (increase bandwidth) avoid excessive aliasing. 

Putting the CPU to work on better upsampling quality (or in my example, band-limiting) is better use of processing cycles than attempting to gain noise-floor level improvement on interpolation error between samples.   Upsampling is, by definition, interpolation.  That DAFX article you linked basically is pointing out strategies of combining sinc interpolation (upsampling) with other polynomial re-sampling (interpolation) algorithms.  It points out a bit of optimization between bandwidth and CPU usage, but it's up to the reader to imagine how the results might change simply by considering band-limiting instead of over-sampling.  In the end interpolation accuracy is improved by having a slower rate of change between samples, so both over sampling and band-limiting are conceptually equivalent means of reducing signalBandwidth/samplingFrequency ratio so that changes between samples are always less than some maximum value.  You could analytically determine this ratio based upon expected/desired noise floor combined with interpolation error.

For example if you were to implement your upsampling algorithm with a Lagrange interpolator you may as well not bother upsampling/downsampling since this is equivalent to computing the value of a sample at time X.  But to downsample, you band-limit, right?  Exactly.  First run your band-limiting filter at the original sample rate then interpolate.  In the end you have to band-limit so you may as well just run it all a the lower rate. 

If higher bandwidth is required then an FIR (sinc) resampler is indicated.   

For guitar processing often band-limiting at 8 kHz is often preferable to get a less brittle sound reminiscent of BBD and tape delays.  These delays are often mixed with full-bandwidth signal so having a low-pass filter with a nonlinear phase response through the upper-end regions adds a frequency response element that sounds "right".
Title: Re: Audio Effects DSP Board
Post by: markseel on September 06, 2016, 05:41:46 PM
Thanks Transmorgrifox - that's a lot of really good info  :icon_biggrin:
Title: Re: Audio Effects DSP Board
Post by: ElectricDruid on September 06, 2016, 06:46:41 PM
The second thing I explored in the code linked is the LFO.  What does it take to make a triangle wave pitch change?  The integral of the tri-wave.

This is an interesting question. For a simple fixed-sample-rate case where the LFO moves the read pointer with between-sample interpolation, this is probably true. For a variable sample rate system like a genuine BBD, it's not so simple. I did some analysis which posted over on my site:

http://electricdruid.net/investigations-into-what-a-bbd-chorus-unit-really-does/ (http://electricdruid.net/investigations-into-what-a-bbd-chorus-unit-really-does/)

The problem is that the variable rate distorts the modulating waveform too. There are ways to model this too, which Antti Huovilainen deals with in one of his DAFX papers.

Tom

Title: Re: Audio Effects DSP Board
Post by: Transmogrifox on September 07, 2016, 01:31:31 PM

This is an interesting question. For a simple fixed-sample-rate case where the LFO moves the read pointer with between-sample interpolation, this is probably true. For a variable sample rate system like a genuine BBD, it's not so simple. I did some analysis which posted over on my site
Interesting read, Tom.  Thanks for going through the trouble of posting it online :D. 

I have given some consideration in the past to some of the things you pointed out, but was not in this case attempting to model a BBD chorus -- just making use of the observation about anti-aliasing filters as a hint for how to reduce computational cost. 

As for the LFO, I was simply looking for the straightforward triangle pitch function, and for the case where an LFO is directly proportional to delay time the simple integral of LFO relationship holds.  I would tend to think this is something the industry has known from day 1 of DSP FX:  once I implemented it I starting hearing a chorus sound reminiscent of 1990's era "post-grunge" and "alternative" rock sounds. (I would be curious to find out what chorus FX unit was used on Collective Soul's Disciplined Breakdown recording). 

Based on my experiments so far it is apparent that the unique sound of the BBD chorus has quite a lot to do with the LFO-to-delay transfer function.  Other effects such as the anti-aliasing, BBD distortion and sampling artifacts are all lesser "spices" in the mix (and much closer to the noise floor).

If the BBD LFO shape is desired, the computational "hammer" is to simply compute every cycle as you and Brian Neunaber pointed out:
Code: [Select]
change_in_pitch = d/dt (1024 / (2*clock_freq) )I would think there must be a more computationally efficient way to this but I haven't given any thought to it  :icon_rolleyes:
Title: Re: Audio Effects DSP Board
Post by: ElectricDruid on September 17, 2016, 07:09:10 PM
If the BBD LFO shape is desired, the computational "hammer" is to simply compute every cycle as you and Brian Neunaber pointed out:
Code: [Select]
change_in_pitch = d/dt (1024 / (2*clock_freq) )I would think there must be a more computationally efficient way to this but I haven't given any thought to it  :icon_rolleyes:

Yeah, this is the point Antti deals with: His suggestion is that the simpler way is to store each sample along with the time it was read in. You can then easily measure d/dt when it comes to the time to output the sample without any mucking about. Costs you some memory, but saves you processor cycles. I did the same thing in my simulation when I was doing the analysis that I posted.

Tom
Title: Re: Audio Effects DSP Board
Post by: mhelin on September 22, 2016, 04:39:36 PM
Yes!  You're ready to rock.

The 'core_dsp.h' has low level DSP support.  I'll be creating an additional library with higher level DSP support - like for the all pass filters, EQ's, cab sims, overdrive/distortion/gain blocks, etc.  Also need to add comments, documentation, and code to illustrate how to use the framework and how to make effects.  This will take some time :-)

The latest board works so the last round of prototype boards will be made.  These will be used to demo the system and to send to various folks for evaluation and experimentation.  I'll send you one - should be in a few weeks.

Hi, and nice to see you back.  Anyway, the core_dsp.h and core_types.h used also in cabsim are missing. Obviously the cabsim isn't proper C code meant to be compiled (with lines starting with ... etc.) but anyway. Can this framework be used also with XMOS StartKIT+ audio slice? Without USB maybe? You can actually load the debugger core part's code from PC via USB on StartKIT, but I don't know how you could get the two cores communicating with each other. I actually played with the USB audio device code using the dynamic loading like in the example in github (https://github.com/xcore/proj_xtag2/tree/master/run_dynamic_xe) using StartKIT. Got some audio out, there were just enough lines for I2S available. Too bad the BOOT ROM / OTP loading cannot be overriden.

I wonder how the HK & China DIY folks make their XMOS boards, like diyinhk.com. Maybe you could contact them / collaborate with to get your boards make and sold. Little bit different scene though, this is not so Hi-Fi but could still be also used for DIY speakers' digital crossovers or for room correction.
Title: Re: Audio Effects DSP Board
Post by: markseel on September 28, 2016, 10:49:51 PM
I removed the audio CODEC and analog interface circuitry - this is now a separate board of the exact same dimensions (1.25" x 0.95").

This XMOS DSP board has connections for GND, Vusb, I2S/PCM/TDM (MCLK, BCLK, WCLM, 4*SDOUT, 4*SDIN), I2C SDA and SCL, and UART TX and RX.  It also has a 10-pin 50mil two-row header for attaching the XTAG-2 -- for programming the device with custom FW.

It can support up to 32x32 channels (32-bit) USB audio, stereo I2S at up to 384 kHz, up to 32x32 channels @ 48kHz of I2S audio via single I2S TDM SDIN/SDOUT or via three separate I2S SDIN/SDOUT signals running I2S, I2C for controlling other peripherals, and UART TX/RX for controlling other peripherals or to support MIDI I/O.

Software for configurable USB audio to I2S bridging is on it's way.  But it also runs the SimpleDSP framework (discussed earlier in this thread) found here: https://github.com/markseel/simpledsp.git
*Note:* I added broad time and frequency domain DSP support by including the XMOS DSP library source files.  Take a look!
Here's the XMOS DSP library API reference: https://github.com/markseel/simpledsp/blob/master/lib_dsp.pdf

Here's a prototype with the XTAG-2/3 JTAG interface (attached to ribbon cable).  This hooks up to an XMOS XTAG-2 or XTAG-3 (can be obtained from Digikey).
(http://i1064.photobucket.com/albums/u361/markseel/Untitled1_1.png)
(http://i1064.photobucket.com/albums/u361/markseel/Untitled2.png)

The boards works fine so far.  Now I need to line up a contract manufacture to make these.  Any suggestions on a CM to make 100 boards would be appreciated :-)

Since I removed the CODEC and analog circuitry from the XMOS board I made an identically sized audio board that connects to it directly via the 100 mil header.  This board is specifically for guitar effects (input designed for pickups).  PCB's are back for this board - just need to populate with parts and test.  Would also like to get a bunch of these made via a CM.
(http://i1064.photobucket.com/albums/u361/markseel/Untitled3.png)
Title: Re: Audio Effects DSP Board
Post by: mhelin on September 29, 2016, 01:04:31 PM

The boards works fine so far.  Now I need to line up a contract manufacture to make these.  Any suggestions on a CM to make 100 boards would be appreciated :-)

Seeedstudio/ Fusion PCB?  https://www.seeed.cc/PCB-%26amp%3B-Assembly-Service-In-SeeedStudio-t-5950.html

Guess there are many such PCBA companies in China. Another is 7pcb (head office in Canada and a sales office in San Jose), you can quote their prices here:

http://www.7pcb.com/PCB-Assembly-Quote.php

For 100 pieces it's about $2000 (dont know what is not included in the price though). Might be little bit more expensive than Seeed.

Those two boards above are about the same size so they could also be panelized for lower costs.
Title: Re: Audio Effects DSP Board
Post by: matze44 on November 10, 2016, 05:12:05 AM
Hi Mark,

Interesting project! Do you have some news about the status?

Greetings,

Matthias
Title: Re: Audio Effects DSP Board
Post by: markseel on November 10, 2016, 08:56:12 PM
The digital and analog board designs are finished. I'll start making these now in small quantities and will post a link here to a website for the boards and firmware soon. The firmware is in progress - updates should be ready in a couple of weeks.
Title: Re: Audio Effects DSP Board
Post by: markseel on December 29, 2016, 11:50:39 PM
Well it's been a while since the last update.  I build a handful of those boards now.  Some worked but others did not.  I suspect that my soldering/reflow skills resulted in questionable ground paddle adhesion, or that my power supply was unstable.  Anyway the design isn't very good as I can't seem to build them reliably.

So on to the next level.  I will be having PCB's designed, fabricated and assembled by a third party and focus myself back on what I do best (firmware and DSP).  Since this board will be designed/built by folks who know what they're doing I upped the design to use the XMOS XUF232.  It has 32 32-bit cores for a total of 2000 MIPs.  It's a 374-pin BGA - way beyond my skills - but to prove the concept I did my own layout anyway to see how it may turn out and to see if the size of the PCB (1.25" x 2.05") would be a problem.  Looks good so it's almost time to pull the trigger on manufacturing prototypes.

The effects SDK posted earlier in this forum will still work the same - no major changes to the API.  Instead of 5 100-MIP cores you'll get 15.  And the audio board is separate.  It's stacked on top of this board (I have custom cases being milled out of solid stainless steel for my effects boxes and they were designed for these board being stacked).

If the design and build of prototypes goes well I'll look to clean up the SDK, manufacture boards, put them in my effects as well as sell the boards to folks looking to do custom USB audio, DSP, and effects stuff.

If anyone reading this has PCB design experience I'd really appreciate feedback on the layout I did before I send the schematic, BOM, and example layout to a design services company - I want to get as close to proper design possible before outsourcing.  I can provide gerber files to anyone who is willing to do a review.

This is a powerful board.  The 32-bit core count was upped from 8 to 32, memory upped from 256 kB to 1024 kB.  You could use this board for: 150 msec (or more) of IR/cabsim, 2 to 48 channel USB audio, 16k to 768k sample rates, etc.

Here's the digital board (XMOS XUF232, power supplies, JTAG, I2S and I2C interfaces, and USB connector):
(http://i1064.photobucket.com/albums/u361/markseel/flexfx_small.png)

I'll post the analog board that stacks on this digital board soon.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on January 01, 2017, 10:08:20 PM
Mark, happy new year and thanks for the update.  Wish I had more to offer on your layout check!  I took the high speed PCB design course about 15 years ago and never really applied it.

I'm still casting about for different platforms for DSP development above the FV-1 which while I consider at the low end, still has a lot on offer.  You board looks so powerful it seems crazy to devote it to a treble booster  :icon_biggrin: .  Small enough to go into a pedal, powerful enough to require a team of highly trained technicians to monitor and maintain it!

I'll certainly want to get one to mess around with as well as (ultimately) some idea of scalability (probably down) as I do have some plans for commercial product development.  Of course, my plans change 3 times a day, but you know...
Title: Re: Audio Effects DSP Board
Post by: loopmasta on January 03, 2017, 11:46:42 AM
Hi Mark. Great project. Do you sell this board as a kit? By the way the github link above is not working.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 03, 2017, 05:50:10 PM
Do you sell this board as a kit?
Yes I'm planning on that.  I'm working to get the boards fabricated and assembled by a contract manufacturer.

By the way the github link above is not working.
OK - I'll get that fixed and also update the code to support the additional 32-bit cores.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 04, 2017, 07:27:59 AM
This is a powerful board.  The 32-bit core count was upped from 8 to 32, memory upped from 256 kB to 1024 kB.  You could use this board for: 150 msec (or more) of IR/cabsim, 2 to 48 channel USB audio, 16k to 768k sample rates, etc.

Here's the digital board (XMOS XUF232, power supplies, JTAG, I2S and I2C interfaces, and USB connector):
[snip]
I'll post the analog board that stacks on this digital board soon.
Mark, so if I understand this correctly, it would be possible to make a multitrack (say 16 inputs) USB audio interface with this board? And then have the DSP do sub-mixing for a number of monitor outputs?
If so, how would this work in practice? I see one would need to add I2S ADC's and DAC's and add microphone preamps.
Does the chip present itself as a generic USB-audio device?

Definitely interested in a kit-board then!
Title: Re: Audio Effects DSP Board
Post by: markseel on January 04, 2017, 10:57:19 AM
The device presents itself as USB Audio class 2.0 and USB MIDI device.  So it's basically a USB audio to I2S and USB to UART bridge with DSP capability.

The firmware can be configured to support up to 32x32 channels (48x48 eventually) audio channels.  For these high channel counts the I2S would be configured to support time-division multiplexed I2S (TDM).  Using the 4-bit ports you could to do I2S, I4S, I8S or I16S on 4 input GPIO's and 4 output GPIO's (64x64 I2S total channels).  So for your application you could either do 1 x I16S, 2 x I8S, or 4 I4S.  There's many CODECs/ADCs/DACs that support I2S/TDM.

USB audio class 2.0 and I2S/TDM can be implemented on a single tile XMOS device (8 cores - like an XUF208 device).  This board is 4 tiles (XUF232 device with 32 cores) so you'd be leaving perhaps 16 to 24 32-bit cores unused.  But if you don't care about that then this board would do the job and you'd have lots of cores for DSP.  BTW mixing audio at 16 or 32 channels in both directions could likely be implemented on one 32-bit core.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 04, 2017, 02:54:14 PM
Interesting.

How would you then configure the mixers? Over the USB MIDI? Leftover cores can always be used for additional EQ etc on the monitoring channels, or for pre-recording processing.

How difficult is such a project going to be? I do program AVR's and I just started getting into the FV-1, but this is going to be 100% new for me. To be honest, I'd rather focus on the hardware :)
Title: Re: Audio Effects DSP Board
Post by: markseel on January 04, 2017, 05:05:04 PM
Yes you'd use USB MIDI.

The SDK for the board defines 'properties' that are used for configuring this sort of stuff (EQ settings, filter parameters, lookup tables, impulse response coefficients, et).  Anytime MIDI data is received over USB it gets distributed to each of the 24 32-bit cores that are used for your custom DSP stuff - in real time.

A property is a 32-bit ID followed by four 32-bit data values for a total property size of 20 bytes.  Assigning the ID in such a way that it doesn't collide with other effects parameters is up to the effects programmer and the community - the firmware doesn't enforce this (i.e. it provides mechanism but does not specify policy).

One approach would be to use one 32-bit ID per four EQ channels where each of the 4 data values holds an EQ band setting (like 0 to 31 representing -15 to +15 dB of gain in 1dB steps) and indexing a table of EQ band filter BiQuad coefficients that are precomputed and stored as arrays of data.

Another approach would be to use one 32-bit ID for each BiQuad filter in the EQ.  So for a 31-band EQ with each band's response set by two BiQuads you'd have 62 ID's and you'd send your BiQuad data from your application running on the PC (or RaspberryPi, etc).

You'd have to consider the noise (zipper noise or pops/clicks) due to changing filter coefficients.  There are straight-forward ways to handle this though.

I'll write up an example EQ for the SDK.


Title: Re: Audio Effects DSP Board
Post by: markseel on January 05, 2017, 01:44:02 PM
Thinking of doing a Kickstarter campaign to raise money for professional PCB design and manufacturing to get this board right.  Any thoughts on whether or not there'd be enough interest in this board/kit to succeed with a Kickstarter fund raising campaign?
Title: Re: Audio Effects DSP Board
Post by: vigilante397 on January 05, 2017, 02:13:17 PM
I'd be interested. I haven't been following this thread the whole time, is there a demo somewhere showing the board in action? I would love to see it working ;D
Title: Re: Audio Effects DSP Board
Post by: markseel on January 05, 2017, 02:16:38 PM
I'll put together a demo :-)
Title: Re: Audio Effects DSP Board
Post by: Ice-9 on January 05, 2017, 05:45:23 PM
Thinking of doing a Kickstarter campaign to raise money for professional PCB design and manufacturing to get this board right.  Any thoughts on whether or not there'd be enough interest in this board/kit to succeed with a Kickstarter fund raising campaign?

I don't see why it wouldn't succeed as a Kickstarter Campaign, A lot of success with Kickstarter is down to good presentation and spreading the word well enough. I suppose how much you need raise would also be a big factor.  I have always thought the line you are following with this DSP is quite different and unique to other DSP board/kits so it very well may benefit from Kickstarter promotion.

 
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on January 05, 2017, 07:02:57 PM
I'd contribute to a Kickstarter.  My concern at this point is that if you go to the top of the performance heap you are essentially putting forth the heart of a gigantic mixing console with assignable effects and all that, and it's not at all clear to me how the "average" person is going to pull together all the I/O and UI to leverage that amount of processing power.   Also the field seems to be getting a bit more crowded recently what with SparkFun having a pedal kit that uses a Teensy, and the Bela gadget based on a BeagleBone Black.  It would be good to have some iterations or versions of this that would be ready to go to perform a smaller specific task, e.g. the IR speaker sim you initially proposed.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 05, 2017, 07:42:32 PM
Great feedback - keep it coming  :)

I'd like to get a sense of how many people would be interested in a board.  Th XEF232 is expensive and I estimate a BOM for this board to be around $35-$50 depending on parts purchasing volumes.  So maybe $100 for the board to cover R&D, BOM, assembly/fabrication, etc.

I'm still planning on a daughter board with ADC/DAC and analog circuitry for guitar applications.  That board wouldn't be very expensive.  Or folks could interface to their own analog board via I2S.

Yep it's a bit of a beast and offers way more DSP than many folks might need at the start - just one core can do multiple speaker crossovers or a 31-band EQ.  Impulse responses takes a lot of DSP - about one core for every 12.5 msec (at 48 kHz).  Overdrive effects, done properly with up/down sampling, look-up tables with interpolation, anti-aliasing filtering, and tone shaping takes about one core per gain stage.

If there was a community site that hosted effects that could downloaded then folks could chain many effects and perhaps then then the DSP power could be utilized (e.g. 3xOverdrive-->multi-voice chorus-->cab sim).  I can get that going with sample/starter effects and a command-line utility to load the effects via USB MIDI.  You could use MIDI to select different chains, change parameters of effects in the chain, set how USB audio is used (to record guitar, mix effects output with computer audio, etc).

I don't have the time for a nice multi-platform GUI application (like an effects builder and/or configurator).  But others could make one since the DSP board is just a USB MIDI device.  Another idea is to have a Raspberry Pi act as a USB MIDI host and send MIDI to control effects parameters based on other inputs (like knobs, touch screens, etc).
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 06, 2017, 04:33:46 AM
Yes you'd use USB MIDI.
[snip]
I'll write up an example EQ for the SDK.
Ok, sounds totally doable-ish.

I would contribute to a kickstarter, if you were going that route. But I agree with Larry. Also, good ideas.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 06, 2017, 05:32:56 AM
Also, I feel a collaboration coming up: if you get Larry involved he might host a forum on holycityaudio?

 :icon_biggrin:
Title: Re: Audio Effects DSP Board
Post by: mhelin on January 06, 2017, 09:09:33 AM
Regarding the BOM you could choose to use XUF224-1024 or even XU224-1024 with external flash (those are cheap and don't add total costs too much). Then maybe if you want to please Hi-fi people the digital part should contain at least two "ultra low phase noise" crystals like NDK NZ2520SD like on diyinhk board (http://www.diyinhk.com/shop/audio-kits/101-xmos-multichannel-high-quality-usb-tofrom-i2sdsd-spdif-pcb.html).

Regarding the analog board (and the whole system) it should either have a custom box of fit to generic board like Hammond 1590BB or if used with multichannel audio applications 1590DD or something like it (maybe with optional 19" rack fittings). So for the stompbox format a codec like CS4272 is a common one, and the board should be fit with 1/4" jack connectors so that the input and output are on opposite sides for generic pedal board use together with a bypass switch so that you can use it without looper (switcher).

Analog board should also have a decent PSU with a 12V DC input using DC/DC converters (switching mode) to get outputs for a 3.3V digital (XEF232 takes over an 1A!)  and at least for a a one analog negative supply -12V for opamps - assuming the +12V input is well regulated. There are these days cheap 12V switch mode supplies available - I use one 48V supply intended for Cisco IP phones on a Neve 1272 mic pre built just and it's very clean. Add a small resistor and a large cap and you'll have a fine analog supply. However, for high end audio it will not be good enough, those guys are so critical about everything, and you rather have DIL sockets for opamps. OPA2604 is a rather good opamp for any use (both guitar fx and hifi - musical enough) though. For digital crossover there should be multichannel ANALOG volume control after DAC (can be builtin if you find such DAC, Cirrus might have one or two). Regarding converters they must have low latency filters (less than 1 ms), again Cirrus ADC/DAC/Codec parts are good, AKM usually use longish FIR filter kernels.

XMOS IDE is propably too much for regular users so you'll need write a multi-platform app (android, ios,pc,mac,linux) with GUI for controlling this device.

Regarding Kicstarter don't hurry, you can find lots of blog posts on tips how to succeed with them.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on January 06, 2017, 09:40:42 AM
Also, I feel a collaboration coming up: if you get Larry involved he might host a forum on holycityaudio?
I would do that if Mark wanted it (and maybe get some user donations to help keep the web site running).  Not sure how much effort I can ultimately put towards this, as I have a few irons in the fire myself with only so many hours in the day.  The Teensy project is leveraging some web-based (and therefore cross platform) code generator based on node-red.  Assuming that it simply spits out C code, maybe it is adaptable to the Xmos platform.  I've ordered a Teensy + audio thing and will be checking it out.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 06, 2017, 11:15:05 AM
Good point about the XU224 and other packages.  They're pin for pin compatible so that would work well - boards could be outfitted with different parts.

I think the analog board should contain the 'quiet' power supply, low phase noise oscillators, and ADC/DAC.  That way this board could just be digital and would remain more generic (USB to I2S) and the analog board could be designed to suit the application (guitar effects vs. high end audio DAC vs. multi-channel mixer).  Good points about the oscillator, OPA and volume control.

If a site hosted algorithms or had a hosted app that spit out 'C' then that would work well I think.  You'd just add that 'C' module to your project and then build it.  Building the app is simple (see earlier posts in this thread).

Keeping with the idea of minimalism for this board (XMOS, power supplies, USB/power, I2S/UART/I2C/GPIO's) I think one could mount this board on to another board that had the footswitch, knobs, jacks, and audio ADC/DAC, and a simple MCU.  This board would then send MIDI to the XMOS board over UART.  Sort like what the Pi community is doing?

Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 06, 2017, 11:56:28 AM
Keeping with the idea of minimalism for this board (XMOS, power supplies, USB/power, I2S/UART/I2C/GPIO's) I think one could mount this board on to another board that had the footswitch, knobs, jacks, and audio ADC/DAC, and a simple MCU.  This board would then send MIDI to the XMOS board over UART.  Sort like what the Pi community is doing?
Indeed, I would prefer to have it modular and not specifically for a certain application/housing.

Larry, I didn't mean to 'push' something on you! And I certainly didn't predict a web-based project builder (that needs to be maintained(!)), but it sounds cool :)

I'm currently looking into that Teensy/node-red audio app, in order to mangle^H^H^H^H^H^Huse it for a configurator for AD7519 based switchers. It could work, but the short route with connector functions is way quicker for the moment.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 06, 2017, 12:06:08 PM
By the way, audiophiles are a funny bunch. I tend to ignore them unless it's for a laugh  ;)

I believe it was Douglas Self who remarked that people obsessed with expensive opamps tend to forget that they are listening to music that went through at least a hundred TL072's before it was committed to CD (or something to that extent).

Oftentimes bad circuits and bad topologies introduce more problems than high-end opamps are able to mitigate.
Title: Re: Audio Effects DSP Board
Post by: mhelin on January 06, 2017, 02:20:33 PM
This board would then send MIDI to the XMOS board over UART.  Sort like what the Pi community is doing?

MIDI could bring this module also to Eurorack synth community which is growing fast. They would also be a target group for the Kickstarter project. Because of the huge power this kind of module could be used to implement algos like additive (Fourier) synthesis.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on January 06, 2017, 04:20:55 PM
Another possibility to consider for control protocol could be Open Sound Control (http://opensoundcontrol.org/introduction-osc).  I got into this as I took an online class in ChucK (http://chuck.cs.princeton.edu/).  I used a Wiimote in conjunction with the Mac program OSCulator (https://osculator.net/) to control synthesis parameters in my ChucK program.  OSC does generally operate using UDP, so the sending and receiving devices need to support a network stack and physical interface.

If you use TouchOSC (http://hexler.net/software/touchosc) then you can also design virtual interfaces using iOS and Android devices.  The nice thing about OSC vs MIDI is that with OSC you are not in the least constrained by what commands you think should be sent (because you can invent your own), whereas you might encounter some limitations using MIDI.  TouchOSC also offers a MIDI bridge application but I think native OSC would be more flexible than MIDI anyway.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 06, 2017, 11:20:22 PM
I suppose many folks would prefer to put this board in a Hammond-like case and add pots and a footswitch.  But I'm putting mine in small 2.5"x2.5"x0.95" cases milled from solid stainless steel (no pots or switches)  :P

Here's an early prototype with an old board that smaller and had the USB jack in a different location:
(http://i1064.photobucket.com/albums/u361/markseel/case1.jpg)
(http://i1064.photobucket.com/albums/u361/markseel/case2.jpg)
Title: Re: Audio Effects DSP Board
Post by: markseel on January 07, 2017, 12:35:55 PM
I can have my machinist make these out of solid aluminum (stainless steel us *really* expensive - harder to machine) for a reasonable cost.  Thinking of offering those as incentives for the kickstarter campaign.  Anyone interested?
Title: Re: Audio Effects DSP Board
Post by: MetalGuy on January 07, 2017, 04:25:27 PM
It definitely looks solid and maybe is quite heavy  :) Machinists hate stainless steel stuff for sure.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 08, 2017, 12:07:35 AM
Here's a FlexFX application example.  It doesn't implement any algorithms but just shows what configuration, events, and functions are used to make a complete application.  I put them in one file for illustration.  This is the only code that needs to be written for the board - all of the USB, I2S, MIDI, I2C and UART code is precompiled and part of the downloadable framework.  An example of how to build (compile this file and link with the framework code to make the firmware executable image) is earlier in this thread.

Code: [Select]
// ================================================================================================
// FlexFX sample application
// ================================================================================================

typedef unsigned char byte;

// ================================================================================================
// System Configuration.  Set these constants to configure USB and I2C.
// ================================================================================================

// ------------------------------------------------------------------------------------------------
// USB Audio configuration.
//
// usb_fs_bit_mask: Each bit indicates what sampling frequency is to be supported for USB audio.
//                  Any combination of bits can be set as long as the ADC/DAC can be configured
//                  accordingly via the I2C functions.
//                  Bit 0 for 44k1, bit 1 for 48K0, bit 2 for 88k2, bit 3 8 for 96k,
//                  bit 4 for 176k4, bit 5 for 192k, bit 6 for 352k8, bit 7 for 384k0
//
// usb_audio_product_id:  16-bit value representing the USB audio product ID
// usb_audio_vendor_id:   16-bit value representing the USB audio vendor ID
// usb_audio_product_str: 10 character string representing the USB audio product name
// usb_audio_vendor_str:  10 character string representing the USB audio vendor name
// ------------------------------------------------------------------------------------------------

const byte  usb_fs_bit_mask       = 0x02;
const int   usb_audio_product_id  = 0x1234;
const int   usb_audio_vendor_id   = 0x1234;
const char* usb_audio_product_str = "FlexFX";
const char* usb_audio_vendor_str  = "Example";

// ------------------------------------------------------------------------------------------------
// I2S Bus configuration.  The I2S bus consists of MCLK (master audio clock), BCLK (sample bit
// clock), WCLK (word select clock), four SDOUT wires for up to four DAC's, and four SDIN wires for
// up to four ADC's.  All sample words are 32-bits supporting 16/24/32 bit samples with either left
// or right justification within the 32-bit word slot.  Time division multiplexing is supported -
// 2 (stereo), 4, 6, 8, 10, 12, 14, and 16 samples per audio cycle, per SDIN/SDOUT wire is allowed
// for up to 64x64 channel I2S/TDM.  The word select format can be I2S or PCM.
//
// i2s_sync_format: 0 for I2S format (low-high WCLK transition one BCLK period before audio cycle.
//                  1 for PCM format (high-low WCLK transition aligned with each audio cycle.
//
// i2s_tdm_slot_count: Defines how many samples are transfered on each SDIN/SDOUT wire for each
//                     audio cycle.  Minimum is 2 (stereo), max is 16.  Must be even number.
// ------------------------------------------------------------------------------------------------

const int i2s_sync_format    = 1;   // 0 for I2S, 1 for PCM
const int i2s_tdm_slot_count = 2;   // 2 (stereo), 4, 6, 8, 10, 12, 14, 16

// ================================================================================================
// System Control.  Use these functions to control system peripherals (using I2C) and to
// distribute effects parameters to audio processing threads (using MIDI data).
// ================================================================================================

// ------------------------------------------------------------------------------------------------
// I2C Functions.  Use these functions to configure the audio ADC/DAC/CODEC upon USB audio config
// change events or to sense pot/switch values via low-speed ADC's and/or I2C port expanders.
//
// i2c_write: Write a sequence of bytes to the addressed device
// i2c_read:  Read a sequence of bytes from the addressed device
// i2c_write_reg:  Write an 8-bit value to the specified 8-bit register of the addressed device
// i2c_read_reg:  Read an 8-bit value from the specified 8-bit register of the addressed device
// ------------------------------------------------------------------------------------------------

extern void i2c_write    ( byte dev_addr, const byte* data, int count );
extern void i2c_read     ( byte dev_addr, byte* data, int count );
extern void i2c_write_reg( byte dev_addr, byte reg_num, byte reg_value );
extern byte i2c_read_reg ( byte dev_addr, byte reg_num );

// ------------------------------------------------------------------------------------------------
// MIDI write function.  Use this function to send MIDI-based property data to each audio thread,
// typically as the result of reading new pot/switch values in the function 'handle_timer' below.
// ------------------------------------------------------------------------------------------------

extern void write_midi_property( const int property[6] );

// ================================================================================================
// Non-audio event handlers.  Code in these event handlers will not effect audio flow.
// ================================================================================================

// ------------------------------------------------------------------------------------------------
// USB and Timer event handlers.  Implement ADC/DAC/CODEC changes via I2C here.
//
// handle_usb_mute: Occurs whenever a USB audio channel is muted or un-muted.
//
// handle_usb_volume_change: Occurs whenever a USB audio channel volume is changed.  0 is minimum
//                           volume and 255 is maximum volume.
//
// handle_usb_rate_change: Occurs whenever the sample rate is changed by the USB host.  The
//                         application should use the I2C functions to set the audio master clock
//                         and configure the ADC/DAC accordingly.
//
// handle_timer: Called at a rate of 1000 Hz. Implement low-speed ADC reading (for pots and/or
// switches) in this function.
// ------------------------------------------------------------------------------------------------

void handle_usb_mute( int audio_channel, int mute_flag )
{
    //i2c_write_reg( 0x00, 0x00, 0x00 );
    //i2c_write_reg( 0x00, 0x00, 0x00 );
}
void handle_usb_volume_change( int audio_channel, byte volume )
{
    //i2c_write_reg( 0x00, 0x00, 0x00 );
    //i2c_write_reg( 0x00, 0x00, 0x00 );
}
void handle_usb_rate_change( int frequency )
{
    //i2c_write_reg( 0x00, 0x00, 0 );
    //i2c_write_reg( 0x00, 0x00, 0 );
}

void handle_timer( void )
{
    //int property[6];
    //int x = i2c_read_reg( 0x00, 0x00 );
    //i2c_write_reg( 0x00, 0x00, 0 );
    //write_midi_property( property );
}

// ================================================================================================
// Audio event handlers.
//
// The initialization functions are all called before audio flow starts and should be used to
// initialize data used by audio processing threads.  The audio processing functions are all called
// once for every audio cycle meaning that they will be expected finish processing before the next
// audio cycle starts. Each processing thread runs in its own 32-bit core and has approximately 100
// MIPs or processing allocation.  The processing functions A1-A5, B1-B5, and C1-C5 form a 15-stage
// processing pipeline for 64 audio samples at each pipeline stage.
//
// Data arriving to thread A1 is from the USB and I2S interfaces and is arranged as 32 USB samples
// followed by 32 I2C samples.  The 64-sample array departing from thread C5 is sent to the USB and
// I2S interfaces and is therefore assumed to be arranged as 32 USB samples followed by 32 I2C
// samples. The 64-sample array passed between all other processes (A2-A5,B1-B5,C1-C4) is user
// defined.
//
// thread_nn_initialize: Initialize data for audio thread nn (A1-A5, B1-B5, or C1-C5)
//
// thread_nn_process: Process audio samples for one audio cycle. 'samples' points to an array of
//                    64 fixed-point (Q1.31 format) audio samples. 'property' points to an array
//                    if 6 integers forming the property used to configure audio processing
//                    functions in real time.  Property[0] is the 32-bit property ID. Property[1:5]
//                    contains the five 32-bit values for the property.
// ================================================================================================

void thread_a1_initialize( void )
{
}
void thread_a1_process( int* samples, const int* property )
{
}

void thread_a2_initialize( void )
{
}
void thread_a2_process( int* samples, const int* property )
{
    // Process audio samples from thread A1, results are sent to thread A3.
    if( property[0] != 0 ) {
        // Check property ID (property[0]) to see of this property applies to this processing
        // thread.
    }
}

void thread_a3_initialize( void )
{
}
void thread_a3_process( int* samples, const int* property )
{
}

void thread_a4_initialize( void )
{
}
void thread_a4_process( int* samples, const int* property )
{
}

void thread_a5_initialize( void )
{
}
void thread_a5_process( int* samples, const int* property )
{
}

void thread_b1_initialize( void )
{
}
void thread_b1_process( int* samples, const int* property )
{
}

void thread_b2_initialize( void )
{
}
void thread_b2_process( int* samples, const int* property )
{
}

void thread_b3_initialize( void )
{
}
void thread_b3_process( int* samples, const int* property )
{
}

void thread_b4_initialize( void )
{
}
void thread_b4_process( int* samples, const int* property )
{
}

void thread_b5_initialize( void )
{
}
void thread_b5_process( int* samples, const int* property )
{
}

void thread_c1_initialize( void )
{
}
void thread_c1_process( int* samples, const int* property )
{
}

void thread_c2_initialize( void )
{
}
void thread_c2_process( int* samples, const int* property )
{
}

void thread_c3_initialize( void )
{
}
void thread_c3_process( int* samples, const int* property )
{
}

void thread_c4_initialize( void )
{
}
void thread_c4_process( int* samples, const int* property )
{
}

void thread_c5_initialize( void )
{
}
void thread_c5_process( int* samples, const int* property )
{
}

// ================================================================================================
// ================================================================================================
Title: Re: Audio Effects DSP Board
Post by: markseel on January 08, 2017, 11:02:51 AM
An example:

1) Pass USB audio output to I2S out (the DAC) and pass I2S input (the ADC) to USB audio input.  USB samples occupy the first 32 samples of the 64-byte sample array and I2S samples occupy the second set of 32 samples.  If no threads are modifying the 64-byte array then audio samples simply loopback to each interface (USB out --> USB in, I2S out --> I2S in).  Copying samples[0:1] to samples[32:33] and also samples[32:33] to samples[0:1] would result in (for stereo) USB out --> I2S out and I2S in --> USB in.  See thread A1.   

Code: [Select]
void thread_a1_initialize( void )
{
}
void thread_a1_process( int* samples, const int* property )
{
    int tmp1 = samples[0]; // Store USB sample[0] (left channel)
    int tmp2 = samples[1]; // Store USB sample[1] (right channel)
    samples[0] = samples[32]; // USB left = I2S left
    samples[1] = samples[33]; // USB right = I2S right
    samples[32] = tmp1; // I2S left = USB left
    samples[33] = tmp2; // I2S right = USB right
}

2) A simple volume control for I2S outputs [0:1] (left and right for stereo).  The initial volume is initialized to 0.  In the thread the samples are multiple by the fractional volume level which ranges from 0 to 0.9999999 (samples and volume are both in Q1.31 format).  The thread also handles a MIDI property that updates the volume level.  See thread A2.

Note: The MIDI property could have arrived to this thread from three sources; (1) USB MIDI from a MIDI host (e.g. a PC), (2) from the UART RX line if connected to an external MIDI source, or (3) from the function 'write_midi_property' that may have been called in the 'handle_timer' function after reading a low-speed ADC using the I2C functions.

Code: [Select]
#include "core_dsp.h"
#define PROPERTY_VOLUME_ID 0x00000001
static a2_volume_q31;
void thread_a2_initialize( void )
{
    a2_volume_q31 = Q31( 0.0 );
}
void thread_a2_process( int* samples, const int* property )
{
    samples[32] = multiply( 31, samples[32], a2_volume_q31 ); // Apply volume to left channel
    samples[33] = multiply( 31, samples[33], a2_volume_q31 ); // Apply volume to right channel
    if( property[0] == PROPERTY_VOLUME_ID ) { // See if it's our property
        a2_volume_q31 = property[1]; // Only one of the five 32-bit property values are used here
    }
}
Title: Re: Audio Effects DSP Board
Post by: stringsthings on January 08, 2017, 08:07:50 PM
This looks really interesting.  Following the thread for news/updates.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 09, 2017, 01:06:32 PM
Note: The MIDI property could have arrived to this thread from three sources; (1) USB MIDI from a MIDI host (e.g. a PC), (2) from the UART RX line if connected to an external MIDI source, or (3) from the function 'write_midi_property' that may have been called in the 'handle_timer' function after reading a low-speed ADC using the I2C functions.
Wow, it gets cooler and cooler!
Title: Re: Audio Effects DSP Board
Post by: markseel on January 09, 2017, 02:17:36 PM
Quote
Note: The MIDI property could have arrived to this thread from three sources; (1) USB MIDI from a MIDI host (e.g. a PC), (2) from the UART RX line if connected to an external MIDI source, or (3) from the function 'write_midi_property' that may have been called in the 'handle_timer' function after reading a low-speed ADC using the I2C functions.

There's some important reasons for this; I only want one area in the FW that handles incoming MIDI data to keep the code simple and to allow for distribution of data.  Keeping to one protocol for USB, UART, and internal (via the timer callback function) also keeps the user code simple - you only parse one data format.  Handling all MIDI in a single part of the FW makes it easy to distribute MIDI data to all interfaces regardless of where the data originates:
1) MIDI over USB is distributed to USB (looped back), to the UART and to the user's algorithms
2) MIDI via the UART RX is sent to UART TX (pass through), to USB and to the user's algorithms
3) MIDI data from the user's timer callback is send to USB, UART TX and to the user's algorithms.
So if you have multiple interferes they can stay in sync as far as settings go and allow both USB and UART interfaces to be updated regardless of what interface made the change.  Also you could use this then for a USB MIDI and UART MIDI bridge.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 09, 2017, 04:47:02 PM
Smart. The only thing I can see going "wrong" is when you use pots connected to the low speed ADC to control certain values: these will be mirrored to the USB-MIDI and the UART-TX, but the other way around is not possible. I say quote-wrong-quote because nothing goes really wrong in the breaking-stuff-sense-of-the-word, but the setting of the pot might not represent the actual value in the DSP if it's modified over USB-MIDI or UART-RX.

... if I understand you correctly ...

Other than that, this enables on-device controls in parallel with host-based controls, that's wicked!

Of course, one could always read pots by a microcontroller which communicates over the UART with the XMOS.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 09, 2017, 05:11:04 PM
Good point.  I agree with you - XMOS itself or a micro-controller sensing pots and updating properties/settings works in only one direction as far as keeping everything sync'd and that things would get out of sync easily.

Hmmm, maybe if the MCU was listening to UART RX for MIDI data from XMOS (in case parameters were updated elsewhere e.g. USB) then I suppose the MCU could light up an LED that indicated that the pots were out of sync -- or something along those lines.  Or you could use rotary encoders and I2C digi-pots (and some kind of display?) but that adds work and complexity.  Not an easy one to solve I guess.

A while back I thought of putting two tiny led's below each knob with either one lit up indicating that the pot value was out of sync with the actual property value.  The left led indicating that the pot's value was too large and that knob needed to be turned counter-clockwise until it reached the correct value, and the other led doing the same except for the value being too small and requiring the knob to be turned clockwise.  LED's would turn of once the pot value matched. 
Title: Re: Audio Effects DSP Board
Post by: markseel on January 09, 2017, 09:00:19 PM
Here's a data-flow diagram of the framework.

(http://i1064.photobucket.com/albums/u361/markseel/flex_flow_1.png)
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 10, 2017, 03:40:54 AM
Hmmm, maybe if the MCU was listening to UART RX for MIDI data from XMOS (in case parameters were updated elsewhere e.g. USB) then I suppose the MCU could light up an LED that indicated that the pots were out of sync -- or something along those lines.  Or you could use rotary encoders and I2C digi-pots (and some kind of display?) but that adds work and complexity.  Not an easy one to solve I guess.
I imagine something like the UI of a digital scope, with 'soft buttons' (context-sensitive function buttons) and rotaries. I would then use the UART and completely bypass the analogue domain (the digi-pots)

Quote
A while back I thought of putting two tiny led's below each knob with either one lit up indicating that the pot value was out of sync with the actual property value.  The left led indicating that the pot's value was too large and that knob needed to be turned counter-clockwise until it reached the correct value, and the other led doing the same except for the value being too small and requiring the knob to be turned clockwise.  LED's would turn of once the pot value matched.
One could implement this with those transparant shaft pots with a duo-led behind it!

Quote
Here's a data-flow diagram of the framework.
What's the total delay/latency from Tile 0 back to Tile 0? < 1ms like you explained earlier in this thread?
Title: Re: Audio Effects DSP Board
Post by: markseel on January 10, 2017, 11:03:05 AM
Quote
What's the total delay/latency from Tile 0 back to Tile 0? < 1ms like you explained earlier in this thread?

Each stage of the audio chain operates on one audio cycle at a time so latency is extremely low.  The latency through the audio processing pipeline is 24 samples.  I2S input and I2S output adds 3 samples for each (6 total) due a buffer and the port's hardware double-buffering.  So for I2S in to I2S out total latency is 30 audio cycles (0.625 msec for 48 kHz Fs and ~0.157 msec for 192 kHz Fs).

Select ADC/DAC/CODEC's with low latency digital filters.  The AK4588's filters have latencies of 5 and 6.8 samples for ADC and DAC respectively.  Analog in to analog out latency would then be around 42 samples (0.875 msec for 48 kHz Fs and 0.219 msec for 192 kHz) -- well under 1 msec and probably as good or better than any other audio effects system available?

Even a not-so-low latency CODEC like the AK4556 (18/Fs for ADC and 21/Fs for DAC) would still provide sub-1msec latency at 192 kHz Fs --> (30+18+21)/192K ~= 0.36 msec. 

USB audio packets (isochronous USB audio 2.0) are transferred at 8000Hz (0.125msec period) and have to be buffered.  The firmware packet FIFO's are 8 deep for incoming packets and 2 deep for outgoing packets adding 1 msec of USB input (host to XMOS) latency and 0.25 msec of USB output (XMOS to host) latency to firmware's audio processing latency of 24/Fs.

Latency through the host OS (data moving through the USB driver and through OS services/API's) varies - I'm not sure how it compares for OS X, Windows, and Linux.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 11, 2017, 12:20:55 PM
Ok, thanks for the explanation.

USB latency and host latency is not a big concern when you do all monitoring by the DSP and not through the DAW, thats the whole point of mixing/monitoring in the interface.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 11, 2017, 02:52:23 PM
Code sample time!

I added the ability to measure how long your DSP code takes to run for each of the 15 processing threads.  Here's an example added to thread A1:

Code: [Select]
void thread_a1_process( int* samples, const int* property, int ticks )
{
    static int pass = 1;

    // Check the tick count for the previous pass through this function.
    // If pass == 2 then we're in our second pass and displaying tick count for pass #1.
    // If pass == 3 then we're in our second pass and displaying tick count for pass #2.
    // Note that pass #1 tick count will always be zero - so have to check for passes after #1.

    if( pass == 2 ) printf( "Pass %u: %04u ticks (%u Hz)\n", pass-1, ticks, 100000000/ticks );
    if( pass == 3 ) printf( "Pass %u: %04u ticks (%u Hz)\n", pass-1, ticks, 100000000/ticks );

    // Make sure processing time does not exceed one audio cycle period.
    // Skip this check for passes before 4 since they will have taken a long time due printing.
    // One tick is 1e-8 second, so one audio cycle at 48 kHz Fs is about 2083 ticks.
    // Subtract 20 ticks for the overhead required to enter/exit this function.
    // The 'tick' value is the tick count for the previous pass.

    if( pass > 3 && ticks > 2083 - 20 )
        printf( "Thread A1 took too long! (%u ticks)\n", ticks );

    pass++;
}

Printed results are:
Code: [Select]
bash-3.2$ xsim test.xe
Hello!
Pass 1: 0018 ticks (5555555 Hz)
Pass 2: 3206 ticks (31191 Hz)
Thread A1 took too long! (2781 ticks)
Goodbye.
bash-3.2$

Pass #1 is measured and printed out in pass #2.
Pass #2 is measured and printed out in pass #3.
Pass #2 takes a lot of ticks due to printing.
Passes #3 and above are checked for a timing violation.  Pass #3 was a violation due to printing.

The function, not doing any DSP, can run without exceeding a cycle of 1/5.5 MHz.  That will go down of course as you add DSP functions.  You can see that calling printf takes a lot of processing time ... so be sure to disable that sort of code when doing real-time audio.  Just use it during simulation and for testing.

Note: You can simulate your code without a board although it's painfully slow.  I'll add a post on that later.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 11, 2017, 08:02:20 PM
The firmware dev kit is available on GitHub:
https://github.com/markseel/flexfx_kit.git

Below I cloned the repo, built the example, and simulated it.

Code: [Select]
bash-3.2$ mkdir github_flexfx_test
bash-3.2$ cd github_flexfx_test
bash-3.2$ git clone https://github.com/markseel/flexfx_kit.git

Cloning into 'flexfx_kit'...
remote: Counting objects: 75, done.
remote: Compressing objects: 100% (69/69), done.
remote: Total 75 (delta 8), reused 71 (delta 6), pack-reused 0
Unpacking objects: 100% (75/75), done.
Checking connectivity... done.

bash-3.2$ cd flexfx_kit
bash-3.2$ /Applications/XMOS_xTIMEcomposer_Community_14.1.1/SetEnv.command
bash-3.2$ ./build.sh example

example.c:157:14: warning: unused variable 'sample' [-Wunused-variable]
    unsigned sample = Q31( magnitude );
             ^
1 warning generated.
xmap: Warning: port "XS1_PORT_1J" on tile[0] is not connected to any pins in this package.
xmap: Warning: port "XS1_PORT_1K" on tile[0] is not connected to any pins in this package.
xmap: Warning: port "XS1_PORT_1I" on tile[0] is not connected to any pins in this package.
Constraint check for tile[0]:
  Cores available:            8,   used:          6 .  OKAY
  Timers available:          10,   used:          8 .  OKAY
  Chanends available:        32,   used:         26 .  OKAY
  Memory available:       262144,   used:      60712 .  OKAY
    (Stack: 4940, Code: 33156, Data: 22616)
Constraints checks PASSED.
xmap: Warning: More than 6 cores used on a tile. Ensure this is not the case on tile running XUD.
Constraint check for tile[1]:
  Cores available:            8,   used:          7 .  OKAY
  Timers available:          10,   used:          7 .  OKAY
  Chanends available:        32,   used:         15 .  OKAY
  Memory available:       262144,   used:      15836 .  OKAY
    (Stack: 2124, Code: 10624, Data: 3088)
Constraints checks PASSED.
xmap: Warning: More than 6 cores used on a tile. Ensure this is not the case on tile running XUD.
Constraint check for tile[2]:
  Cores available:            8,   used:          7 .  OKAY
  Timers available:          10,   used:          7 .  OKAY
  Chanends available:        32,   used:         15 .  OKAY
  Memory available:       262144,   used:       8876 .  OKAY
    (Stack: 628, Code: 5372, Data: 2876)
Constraints checks PASSED.
xmap: Warning: More than 6 cores used on a tile. Ensure this is not the case on tile running XUD.
Constraint check for tile[3]:
  Cores available:            8,   used:          7 .  OKAY
  Timers available:          10,   used:          7 .  OKAY
  Chanends available:        32,   used:         15 .  OKAY
  Memory available:       262144,   used:       8860 .  OKAY
    (Stack: 652, Code: 5336, Data: 2872)
Constraints checks PASSED.

bash-3.2$ xsim example.xe

Hello!
Pass 1: 0018 ticks (5555555 Hz)
Pass 2: 3206 ticks (31191 Hz)
Thread A1 took too long! (2781 ticks)

^Cbash-3.2$
Title: Re: Audio Effects DSP Board
Post by: markseel on January 12, 2017, 12:17:20 PM
Here's a dimensional drawing of the board showing the USB connector (left), mounting holes, input/output pins along the top (for power, ground, UART, I2C and I2S/TDM), and the JTAG/XTAG interface.

(http://i1064.photobucket.com/albums/u361/markseel/flexfx_4.png)
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 12, 2017, 01:14:20 PM
I'm getting

Code: [Select]
bash-3.2$ xsim example.xe
ERROR: No port 'XS1_PORT_1A' found on node 32788 core 0

Am I doing something wrong or missing something? Installed latest (14.2.4) XMOS tools; running on Mac OS 10.10.5.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 12, 2017, 01:23:55 PM
Not sure what that means yet - I'll upgrade my version and rebuild ...
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 12, 2017, 01:28:16 PM
I didn't actually git clone, I downloaded the -master.zip and unzipped and cd'ed into that.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 12, 2017, 01:29:42 PM
Yeah that's fine - either way would work.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 12, 2017, 01:59:13 PM
Fixed for xTIMEcomposer 14.2.x and pushed to GitHub.
Title: Re: Audio Effects DSP Board
Post by: mhelin on January 12, 2017, 04:38:34 PM
Code: [Select]
[quote author=markseel link=topic=114354.msg1079120#msg1079120 date=1484182940]

bash-3.2$ cd flexfx_kit
bash-3.2$ /Applications/XMOS_xTIMEcomposer_Community_14.1.1/SetEnv.command
bash-3.2$ ./build.sh example
...
[/quote]

Tip for Windows users: replace the Linux line continuation characters '\' (backslash) with '^' (caret) in build.bat to be able to do the build.

The just run the commands

C:\your\workdir>build.bat example
C:\your\workdir>xsim example.xe


Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 12, 2017, 04:47:32 PM
Fixed for xTIMEcomposer 14.2.x and pushed to GitHub.
Yep, works now! Thanks!
Title: Re: Audio Effects DSP Board
Post by: markseel on January 12, 2017, 08:12:49 PM
Here's another code example; A stereo 15-band graphic EQ with 4th order filters (two cascaded biquad's) for each band.  The frequency band filters are processed in cascaded form therefore the complete EQ frequency response can be processed as 30 cascaded biquad filters.

The filter coefficients are not hard-coded for specific frequency responses (although they could be if desired) but rather are set to 0.0 and later loaded up via MIDI by a host computer allowing band Q, gain, and frequency to be calculated by the host machine as settings change.  This method works well when using USB MIDI due to its high data rate and low latency.

Both left and right channels are both processed in one processing thread and easily satisfies timing for a 48 kHz sampling rate.  Keep in mind that although thread A1 is doing work the threads A2-A5, B1-B5 and C1-C5 are unused and still have approximately 100 MIPs each do to additional processing.

Code: [Select]
bash-3.2$ xsim example_eq.xe
1192 ticks (83892 Hz)

Code: [Select]
#define MIDIPROP_GRAPHICEQ          0x12345600
#define MIDIPROP_GRAPHICEQ_COEFFS_L (MIDIPROP_GRAPHICEQ+0x00)
#define MIDIPROP_GRAPHICEQ_COEFFS_R (MIDIPROP_GRAPHICEQ+0x20)
#define MIDIPROP_GRAPHICEQ_GAINS    (MIDIPROP_GRAPHICEQ+0x40)

#define GRAPHICEQ_BAND_COUNT   15
#define GRAPHICEQ_FILTER_COUNT  2

int32_t graphiceq_coeffsL_q28[GRAPHICEQ_BAND_COUNT*GRAPHICEQ_FILTER_COUNT*5] =
{
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 01 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 01 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 02 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 02 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 03 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 03 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 04 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 04 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 05 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 05 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 06 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 06 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 07 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 07 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 08 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 08 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 09 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 09 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 10 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 10 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 11 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 11 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 12 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 12 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 13 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 13 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 14 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 14 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 15 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 15 Biquad 2
};

int32_t graphiceq_coeffsR_q28[GRAPHICEQ_BAND_COUNT*GRAPHICEQ_FILTER_COUNT*5] =
{
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 01 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 01 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 02 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 02 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 03 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 03 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 04 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 04 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 05 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 05 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 06 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 06 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 07 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 07 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 08 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 08 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 09 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 09 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 10 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 10 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 11 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 11 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 12 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 12 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 13 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 13 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 14 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 14 Biquad 2
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 15 Biquad 1
    Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), Q28(0.0), // Band 15 Biquad 2
};

int32_t graphiceq_stateL_q28[GRAPHICEQ_BAND_COUNT*GRAPHICEQ_FILTER_COUNT*4];
int32_t graphiceq_stateR_q28[GRAPHICEQ_BAND_COUNT*GRAPHICEQ_FILTER_COUNT*4];

// These pre/post gains are fixed-point Q28 formatted values ranging from (-8.0 to +7.999...)
int32_t graphiceq_pregainL_q28, graphiceq_pregainR_q28;
int32_t graphiceq_postgainL_q28, graphiceq_postgainR_q28;

void thread_a1_initialize( void )
{
    graphiceq_pregainL_q28 = graphiceq_pregainR_q28 = 0;
    graphiceq_postgainL_q28 = graphiceq_postgainR_q28 = 0;
    for( int ii = 0; ii < 15*2*4; ++ii ) graphiceq_stateL_q28[ii] = 0;
    for( int ii = 0; ii < 15*2*4; ++ii ) graphiceq_stateR_q28[ii] = 0;
}

void thread_a1_process( int* samples, const int* property, int ticks )
{
    static int pass = 0;

    // Process left channel sample
    samples[0] = lib_dsp_math_multiply( samples[0], graphiceq_pregainL_q28, 28 );
    samples[0] = lib_dsp_filters_biquads( samples[0],
                                          graphiceq_coeffsL_q28, graphiceq_stateL_q28,
                                          GRAPHICEQ_BAND_COUNT*GRAPHICEQ_FILTER_COUNT,
                                          28 );
    samples[0] = lib_dsp_math_multiply( samples[0], graphiceq_postgainL_q28, 28 );

    // Process right channel sample
    samples[1] = lib_dsp_math_multiply( samples[1], graphiceq_pregainR_q28, 28 );
    samples[1] = lib_dsp_filters_biquads( samples[1],
                                          graphiceq_coeffsR_q28, graphiceq_stateR_q28,
                                          GRAPHICEQ_BAND_COUNT*GRAPHICEQ_FILTER_COUNT,
                                          28 );
    samples[1] = lib_dsp_math_multiply( samples[1], graphiceq_postgainR_q28, 28 );

    // Check for a property update to the pre and post gain values
    if( property[0] == MIDIPROP_GRAPHICEQ_GAINS )
    {
        graphiceq_pregainL_q28  = property[1];
        graphiceq_pregainR_q28  = property[2];
        graphiceq_postgainL_q28 = property[3];
        graphiceq_postgainR_q28 = property[4];

    }
    // Check for a property update to the left EQ filter bank
    else if( (property[0] & 0xFFFFFFF0) == MIDIPROP_GRAPHICEQ_COEFFS_L )
    {
        int filter_num = property[0] - MIDIPROP_GRAPHICEQ_COEFFS_L - 1;
        set_property( graphiceq_coeffsL_q28 + 5 * filter_num, property );
    }
    // Check for a property update to the right EQ filter bank
    else if( (property[0] & 0xFFFFFFF0) == MIDIPROP_GRAPHICEQ_COEFFS_R )
    {
        int filter_num = property[0] - MIDIPROP_GRAPHICEQ_COEFFS_L - 1;
        set_property( graphiceq_coeffsL_q28 + 5 * filter_num, property );
    }

    if( ++pass == 2 ) printf( "%u ticks (%u Hz)\n", ticks, 100000000/ticks );
}
Title: Re: Audio Effects DSP Board
Post by: mhelin on January 15, 2017, 03:32:24 PM
Is it possible to do some multi-rate filtering using this framework? I mean using first the lib_dsp_filters_decimate using some decimation factor like 64 for 750 Hz intermediate sample rate to be able to have finer control of bass frequencies for controlling room modes and then interpolate back to 48 kHz using the lib_dsp_filters_interpolate? That's what some room EQ devices use like this:

http://www.dspeaker.com/en/products/20-dual-core.shtml
Reviewed here: http://www.theabsolutesound.com/articles/dspeaker-anti-mode-20-dualcore-digital-signal-processor/

---

DSP Filters:

Anti-Mode 2.0 Multi-Rate (FIR & IIR)
House Curve filter
Linear-Phase Tilt
Parametric EQs
Adjustable Infrasonic
Adjustable cross-over

---
The above product uses multiple small in-house developed DSP chips on their products, but guess a single multi-core Xcore processor could do the job easily.

Also there is the Room EQ Wizard (REW for short) application which can output the correction filters in multiple formats. If you ever decide to implement the MIDI protocol and format for the filters you could ask REW developers to include support for your format into the software.

See https://www.roomeqwizard.com/#
Title: Re: Audio Effects DSP Board
Post by: markseel on January 15, 2017, 04:04:47 PM
Quote
Is it possible to do some multi-rate filtering using this framework?

Yes it's definitely possible  :icon_biggrin:.

The framework is there to handle the USB, I2S/TDM, I2C, UART, MIDI, and data flow duties and to provide the application structure.  There's plenty of MIP's available for multi-rate DSP.  The DSP libraries' interpolation/decimation FIR functions may be fine as-is but you can also look at the source code for these functions and possibly come up with code that's better tuned for what you need to do. 

You could also use the XMOS sample-rate conversion libraries (SSRC and ASRC support).  Just copy the SRC library source files into the directory for the framework and add the .C and/or .XC files to the build script.

https://www.xmos.com/support/libraries?subcategory=Audio

Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 16, 2017, 03:42:05 PM
Last weekend I came across this: http://amtelectronics.com/new/manuals/Pangaea-CP-16-M-ENG.pdf

Could this be an XMOS?

Haven't found it for sale yet, though.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 16, 2017, 03:50:46 PM
Yeah another poster in this forum saw this as well. It looks like a nice little module. Based on its impulse response capability I'd guess that it's based on a ARM Cortex M4 with floating point support in hardware. Or maybe one of the smaller XMOS devices? About 1/3 of the power of my board but plenty of power for some guitar effects and delay depending on how much RAM is available. Latency is over 1msec but I suspect that it's acceptable for many folks.  Looks pretty cool but there's no API as far a I know for implementing your own stuff.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 18, 2017, 04:55:35 PM
Got some more info on the AMT board: $78 in quantities <10; available Real Soon Now TM.

More questions, not necessarily FlexFX/XMOS related but more general DSP: how would a kind of guitar-synth be implemented? A whole bunch of filters + gates/triggers or by FFT? With FFT one will introduce latency because of the frame/window size, but with high samplerates (96kHz?) and small framesizes (1k?) that might be ok-ish.

I ask because daydreaming about things to use your board for might be to do a kind of EHX B-9/C-9/etc. workalike. In this case FFT might actually be ok, if you start a 'click' sample right away on the attack of the notes but only start the correct pitched sample after analysis.
Title: Re: Audio Effects DSP Board
Post by: markseel on January 18, 2017, 08:16:10 PM
Quote
Got some more info on the AMT board: $78 in quantities <10; available Real Soon Now TM.
Good info.  FlexFX will offer much higher performance per cost.  I suspect that the board will be perhaps $100-$125 and have 3x the performance in addition to full programmability, DSP libraries, MIDI support and high channel count (up to 32x32) USB and I2S audio support.

Quote
how would a kind of guitar-synth be implemented?
I don't really know.  I focus on time-domain effects myself.  Perhaps others in this forum are familiar with synth techniques?  But you could react to MIDI in real-time which makes for interesting possibilities.  Also, the DSP library supports FFT and iFFT and full source code for the DSP library is included (free from of XMOS Ltd.).
Title: Re: Audio Effects DSP Board
Post by: markseel on January 18, 2017, 08:57:50 PM
I added a Python script to the FlexFX kit on GitHub that creates time and frequency domain plots of output data.

Here's the test code.  It just prints the ASCII/HEX value for each Q1.31 formatted fixed-point sample for a 1000 Hz sine wave with Fs=48kHz.  Note that it generates 8192 samples.  If you simulate this it will take a long time!  The best way to run this is to use the board attached to the XTAG2 (the JTAG interface) and run the program on the board - it won't run in real-time due to the printf's but it will create the output data much faster.

Code: [Select]
#ifdef TEST
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#endif

static double PI2 = (double) (2*3.141592653);
static double sine( double time, double frequency ) {return sin(time*PI2*frequency);}

void thread_a1_initialize( void )
{
}
void thread_a1_process( int* samples, const int* property, int ticks )
{
    #ifdef TEST
    static int count = 0;
    unsigned sample = Q31( sine( count / 48000.0, 1000.0 ) );
    printf( "%08x\n", sample );
    if( ++count == 32 ) exit(0);
    #endif
}

Code: [Select]
bash-3.2$ xsim example_plot.xe > out.txt

bash-3.2$ python plot.py out.txt 31 time
bash-3.2$ python plot.py out.txt 31 time 100 300
bash-3.2$ python plot.py out.txt 31 freq lin
bash-3.2$ python plot.py out.txt 31 freq log

(http://i1064.photobucket.com/albums/u361/markseel/plot1.png)(http://i1064.photobucket.com/albums/u361/markseel/plot2.png)(http://i1064.photobucket.com/albums/u361/markseel/plot3.png)(http://i1064.photobucket.com/albums/u361/markseel/plot4.png)
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on January 19, 2017, 02:58:25 PM
Quote
how would a kind of guitar-synth be implemented?
I don't really know.  I focus on time-domain effects myself.  Perhaps others in this forum are familiar with synth techniques?  But you could react to MIDI in real-time which makes for interesting possibilities.

I actually meant the analysis of the guitar signal, which might then poop out MIDI to some other box (synth), or generate sounds from within the XMOS. But:
Quote
Also, the DSP library supports FFT and iFFT and full source code for the DSP library is included (free from of XMOS Ltd.).

I have to admit I haven't really dived into this (read: googled any of it), but the FFT functionality sounds like a good thing to make use of.

So many projects, so little time! *sigh*
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on January 19, 2017, 07:55:37 PM
Guitar synth a'la EHX B3 can be approached using an FFT based "Phase Vocoder".  See:  https://guitarextended.wordpress.com/2012/04/04/polyphonic-synth-using-phase-vocoder-in-pure-data/

There is also an online service called "Heavy (https://enzienaudio.com/)" that purports to translate Pure Data to portable C.  It is offered as a development solution for the Bela platform.

I haven't had time to try any of this either!!!  Although I did try out the Phase Vocoder in Pure Data (just run it on your PC or Mac).

Title: Re: Audio Effects DSP Board
Post by: markseel on January 22, 2017, 07:49:32 PM
Going to start adding effects and effects support modules while waiting for hardware.  Will add LFO, up/down sampling, parametric and graphic EQ's, TANH approximation, etc.  And eventually chorus, flanging, overdrive, etc.

Just added support for LFO's.  You can create as many LFO's as you want - limited only by memory and MIP's.
The LFO supports sine, half-sine, triangle, saw-up, and saw down (triangle and saw still need testing).

The sine mode uses a lookup table and 2nd order Lagrange interpolation.  Graphs show how clean the a 10 Hz sine at 48k Fs is.

Both the original lookup table (green) result and the interpolated result (blue) are plotted - you can see how jagged the non-interpolated version is and in the FFT plot the interpolated result doesn't have the harmonics from abrupt look-up table value changes.  Nice and smooth.

There's been other small changes to DSP support and changes will continue as the kit matures so be sure to pull updates if you're trying out the code :-)

Here's how to add some LFO's:
Code: [Select]
#include "efx_lfo.h"

static efx_lfo_t lfo1;

void thread_a1_initialize( void )
{
    // Initialize LFO: 10 Hz Sine wave at 48000 Fs
    int period_q30 = FQ(30,+10.0/48000.0); // Q30 fixed point value from floating point value
    efx_lfo_initialize( &lfo1, EFFECTS_LFO_TYPE_SINE, period_q30 );
}
void thread_a1_process( int* samples, const int* property, int ticks )
{
    // Get next LFO sample
    int sample = efx_lfo_process( &lfo1 );
}

Time and FFT plots of 10 Hz sine:
(http://i1064.photobucket.com/albums/u361/markseel/plot5.png)
(http://i1064.photobucket.com/albums/u361/markseel/plot6.png)
Title: Re: Audio Effects DSP Board
Post by: briandress on February 03, 2017, 01:33:57 PM
would this be something to make for an amp sim, cab sim, IR loader box that I could carry around in my pocket?

i am just a guitar nerd and really have not much knowledge about what you are all talking about in this thread. trying to read through but im getting confused lol
Title: Re: Audio Effects DSP Board
Post by: markseel on February 03, 2017, 07:12:49 PM
This board is intended to be a small and powerful DSP and USB audio/MIDI for effects and cabsims.  It's just the DSP, DAC/ADC digital interfaces, and USB audio/MIDI interfaces - so sort of the central portion of a full MIDI controlled multi-effects / cabsim system.  My plans are to pair it with an audio board (with guitar input), put in a small case (2.5" x 2.5" x 1.0") and allow it to be loaded with effects/cabsims via USB and function as a DI/effects/cabsim chain in one small USB-powered box.  Pretty much like the other multi-effects units out there that support direct-input for recording, output for playback or jamming, effects control and multi-effects chains, and MIDI support.  Only this unit is smaller, simpler (only USB - which may be good for some folks bad for others :-) and lower latency - somewhere on the order of 1 msec or less for effects + cabsim, and <0.5 msec for just cabsim.  Hope to have final numbers soon.  If this goes well I'd like to kick-starter the building of more units to sell.  There's a software dev kit started for those who want to roll their own effects, experiment with DSP, or make high channel-count and/or high sample-rate audio interfaces.
Title: Re: Audio Effects DSP Board
Post by: markseel on February 04, 2017, 12:24:37 PM
Board/PCB is being laid out (by the pro's, not me :-) - here's initial component placement.  Pretty tight - there's a lot of stuff in a small space.  The first rev of layout with full routing should be finished next week!

(http://i1064.photobucket.com/albums/u361/markseel/flexfx_rev1a.png)

I'm designing the audio daughter board in parallel with the XMOS board layout.  The audio board will be using the CS4272 DAC/ADC.  Will post that layout soon.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on February 06, 2017, 02:19:22 AM
Hmmm, maybe if the MCU was listening to UART RX for MIDI data from XMOS (in case parameters were updated elsewhere e.g. USB) then I suppose the MCU could light up an LED that indicated that the pots were out of sync -- or something along those lines.  Or you could use rotary encoders and I2C digi-pots (and some kind of display?) but that adds work and complexity.  Not an easy one to solve I guess.

A while back I thought of putting two tiny led's below each knob with either one lit up indicating that the pot value was out of sync with the actual property value.  The left led indicating that the pot's value was too large and that knob needed to be turned counter-clockwise until it reached the correct value, and the other led doing the same except for the value being too small and requiring the knob to be turned clockwise.  LED's would turn of once the pot value matched.
Over the weekend I came across these:

http://www.ebay.com/itm/1-3-Annular-LED-Ring-Display-Green-Bars-Red-Dot-Rotary-Encoder-or-Clock-/251437248842?hash=item3a8ad3f14a:g:saQAAOxyrM5TJHaW
Title: Re: Audio Effects DSP Board
Post by: free electron on February 06, 2017, 04:21:51 AM
Or a DIY option i designed a while ago: I2C controlled LED ring:
http://www.diystompboxes.com/smfforum/index.php?topic=113822



Only 2 pins can drive up to 8 of such boards.
Title: Re: Audio Effects DSP Board
Post by: markseel on February 06, 2017, 10:25:02 AM
That's awesome - those multicolor LED's look fantastic.  It would be really cool to have a box with maybe three of these, some foot-switches, and MIDI output to the FlexFX board.  The cap-sense is really interesting too.

Quote
Over the weekend I came across these:

http://www.ebay.com/itm/1-3-Annular-LED-Ring-Display-Green-Bars-Red-Dot-Rotary-Encoder-or-Clock-/251437248842?hash=item3a8ad3f14a:g:saQAAOxyrM5TJHaW

Nice.  Maybe those could be combined with the free electron's PSOC solution.
Title: Re: Audio Effects DSP Board
Post by: markseel on February 16, 2017, 07:45:08 PM
The FlexFX digital board layout is complete and ready for a prototype production run!

(http://i1064.photobucket.com/albums/u361/markseel/flexfx_layers%20small.png)
Title: Re: Audio Effects DSP Board
Post by: imaradiostar on February 16, 2017, 09:54:37 PM
Looks good! Is it going to Osh?

Is there a mating board with a pair of AK4556's and a regulator for 9v guitar input? Should I design one?

What about a bluetooth module? That of course assumes a mating software tool. I'm assuming your USB based application could be adapted to bluetooth. I know a guy that writes android code for a living, maybe I could recruit him.

;)

Jamie
Title: Re: Audio Effects DSP Board
Post by: markseel on February 16, 2017, 11:36:43 PM
I can't sent this to OSH I don't think unless they're able to place that BGA on the board for me.  I'll check.

Quote
http://Is there a mating board with a pair of AK4556's and a regulator for 9v guitar input? Should I design one?

I'm designing an audio board but it's not exactly like the one you're describing.  I'd be more than happy to collaborate on that.  Do you do PCB layout?  If not I can design the PCB and put it up on OSH Park.

Quote
http://What about a bluetooth module?

Totally agree that BLE would be a good way to control effects.  I've done BLE firmware development on various embedded projects so happy to help with this if folks are interested.  The board's UART TX/RX can be used to comminate with a BLE module that runs a complete BLE stack (like the BlueGiga BLE112/BLE113).  You can program these and have them exchange data with the DSP board via those UART lines.

Quote
http://I know a guy that writes android code for a living, maybe I could recruit him.

That'd be cool.  Same with iOS.  I'd like to be able to control the effects/DSP board from a mobile app.

Title: Re: Audio Effects DSP Board
Post by: imaradiostar on February 16, 2017, 11:53:07 PM
In all honesty I've not done any real digital board design in Eagle or the like. I seem to recall using PCB123 or somesuch but that was ages ago. I've designed quite a few stencil transfer jobs and even produced the artwork using vizio so that they looked nice but that's nowhere near the same thing. I've only recently started again on that sort of work once I realized that Osh is so cheap and can do a four layer board.

All bluetooth posturing aside- I think your idea is good and the best way to get traction is to get it built and working. A computer based interface and dev environment was your goal anyway, right? Forget bluetooth, get it built.

One thing I HAVE done, though, is solder BGAs. I have an oven at work. We'll talk.

Jamie
Title: Re: Audio Effects DSP Board
Post by: markseel on February 17, 2017, 11:00:55 AM
For my effects I'm doing this:

Mono Input --> Digital Preamp * 2 --> Graphic EQ * 2 --> Modulation * 2 --> Mixer/Spatializer --> Cabsim --> Stereo Output

There's two preamp/EQ/modulation blocks so that they can be run in parallel and mixed to create a thicker sound. 

The digital preamps model 3-stage triode gain stages.  Each 3-stage preamp feeds a 9-band graphic EQ for final tone shaping.  The EQ's frequencies and gains can all be adjusted (so an EQ's frequency bands can be tailored to shaping interests).  And those two then each feed separate 3-voice modulators (chorus/flanger/delay).  So two independent effects chains.

Both preamp/EQ/modulator effects audio paths feed a mixer and spatializer (mono to stereo conversion).  The mixer allows the two preamp/EQ/mod paths to feed a left channel and right channel cab simulator with the desired mixes.  The spatializer allows the use of a single preamp/EQ/mod channel to feed stereo cab sim's (mono-to-stereo conversion).  Using a mono cab sim vs stereo cab sim allows for longer IR's.  And using one preamp/EQ/mod rather than two also allows for larger cab sim IR's.  The cab sim IR length grows to water MIP's is available after configuring the preamp/EQ/modulator effects.  Also; the preamp or modulator for each effects chain can be enabled/disabled - further freeing up MIP's for longer IR's.  Therefore the IR support ranges from 10 msec to 80 msec depending on effects configuration.

The preamp/EQ/modulator effects are fully parameterized.  There's a total of ~70 parameters ...

Preamp: 10 for each of the 3 preamp stages
GraphicEQ: Final gain, 9 band frequencies, 9 band gains
Modulator: 9 for each of the 3 voices

... allowing the effects designer to experiment and create something new, or to model something that already exists.  A GUI app to aid with this is in the works.  All parameters are accessable via USB MIDI and/or serial UART MIDI.
Title: Re: Audio Effects DSP Board
Post by: markseel on March 07, 2017, 07:40:30 PM
These IR's are in WAV format.  This board and effects framework will support them at the 48 kHz sample rate.
https://www.celestionplus.com
https://www.celestionplus.com/ir-overview/
Title: Re: Audio Effects DSP Board
Post by: dapeegoo on March 21, 2017, 03:51:27 PM
Hi Mark,

I just sent you a PM. Are you selling your IR loader pedal yet? Would love to try it out!
Title: Re: Audio Effects DSP Board
Post by: orbitbot on March 21, 2017, 05:57:37 PM
I also do Android (amongst other) programming for a living, so I could probably chip in somewhere or at least give a codebase a lookover. I have just gotten started on doing embedded & audio stuff so that territory isn't as familiar yet. Regarding the whole bluetooth implementation idea though, do you all feel this is an appropriate action to take at this point in time? Reading through the post history I get the feeling that perhaps the main board should get onto solid ground and into end users hands before its that feasible to start tweaking (I see Android & BT functionality as something further down the line).
Title: Re: Audio Effects DSP Board
Post by: markseel on March 22, 2017, 10:38:51 AM
Quote
Are you selling your IR loader pedal yet?
Not yet.  After I have enough money to make the prototypes and prove that the HW design is correct then I'll look to produce these in larger quantity.  Hopefully soon!

Quote
... do you all feel this is an appropriate action to take at this point in time?
Not for me as I'm focused on getting the XMOS board and the effects/cabsim SDK finished.  The board is fairly basic - USB, DSP, and I/O's for I2S, I2C, and UART.  One could add support for a external BT or BLE module though.
Title: Re: Audio Effects DSP Board
Post by: markseel on April 04, 2017, 02:43:09 PM
Prototype boards are in production!
Should be ready for testing in 1 to 2 weeks.
Title: Re: Audio Effects DSP Board
Post by: markseel on April 19, 2017, 05:08:26 PM
Prototype boards are back and ready for testing.
32 cores and 2000 MIPS in a small package!
(http://i1064.photobucket.com/albums/u361/markseel/flexfx_top_1.png)
(http://i1064.photobucket.com/albums/u361/markseel/flexfx_bot_1.png)
Title: Re: Audio Effects DSP Board
Post by: Ice-9 on April 19, 2017, 05:47:44 PM
These are looking great Markseel, I look forward to your testing results.
Title: Re: Audio Effects DSP Board
Post by: micromegas on April 24, 2017, 04:55:10 AM
Those boards look nice indeed! Lots of power in such a small package
Title: Re: Audio Effects DSP Board
Post by: markseel on April 24, 2017, 02:08:55 PM
Board works  :D  Can load and run firmware via JTAG.  Next up I'll finalize the development kit for a first release (it's in Github if you want to see a prelim version).  Will also have a stereo cab simulator (impulse response convolution) ready soon as an example app for the dev kit.
Title: Re: Audio Effects DSP Board
Post by: Ice-9 on April 24, 2017, 02:26:36 PM
Board works  :D  Can load and run firmware via JTAG.  Next up I'll finalize the development kit for a first release (it's in Github if you want to see a prelim version).  Will also have a stereo cab simulator (impulse response convolution) ready soon as an example app for the dev kit.

Great progress, please count me in for a board when you are ready to release them Mark,   :icon_cool:
Title: Re: Audio Effects DSP Board
Post by: markseel on April 24, 2017, 02:33:17 PM
Will do.  Hopefully we can get lots of folks interested in order to decrease the cost per board.
Title: Re: Audio Effects DSP Board
Post by: micromegas on April 24, 2017, 05:09:10 PM
Will do.  Hopefully we can get lots of folks interested in order to decrease the cost per board.

I am definitely interested in one
Title: Re: Audio Effects DSP Board
Post by: orbitbot on April 24, 2017, 06:34:52 PM
I'd also be interested in a board when the time comes along, although I'm still a bit wary of construction complexity and screwing up something expensive while trying to DIY. Which is to say that I'm a bit price-sensitive, but following the development with great interest 8) A Kickstarter or something as mentioned earlier in the thread sounds like a reasonable approach to me.
Title: Re: Audio Effects DSP Board
Post by: markseel on April 24, 2017, 06:40:39 PM
... a bit wary of construction complexity and screwing up something...

Can you elaborate on that?  Maybe there's something we can do to make adoption easier.  The boards will be fully assembled so you'd have to add mounting screws and a 100-mil pin header or perhaps solder wires to the header holes.

Also, a cheap guitar/analog interface board is in the works so then you'd just have to connect it to the XMOS board and wire up your audio jacks and switches and what-not.  Thoughts?
Title: Re: Audio Effects DSP Board
Post by: mizgreen on April 25, 2017, 01:11:31 AM
Definitely like to have one! though I'm not familiar with coding stuff.
How many IRs it can hold at once?
I need a small Cabsim board inside of my DIY preamp pedal.
Title: Re: Audio Effects DSP Board
Post by: orbitbot on April 25, 2017, 02:32:48 AM
... a bit wary of construction complexity and screwing up something...

Also, a cheap guitar/analog interface board is in the works so then you'd just have to connect it to the XMOS board and wire up your audio jacks and switches and what-not. 

Oh, must have missed the part about the guitar/analog interface if it's been mentioned somewhere. Sounds reasonable enough. It seems like an interface like that where you can do the volume and current scaling to whatever the digital boards or codecs supports (and back afterwards) is the missing element (or something you're expected to be able to whip up) in a lot of potential effects solutions for guitar, but it's all a bit over my head electronics-wise.
Title: Re: Audio Effects DSP Board
Post by: glennalday on April 25, 2017, 07:55:33 PM
This seems to fit my needs for a multichannel usb audio interface. Please count me in! I wan't one! :)
Title: Re: Audio Effects DSP Board
Post by: markseel on April 25, 2017, 11:07:02 PM
This seems to fit my needs for a multichannel usb audio interface. Please count me in! I wan't one! :)

Great.  This little board can do up to 32x32 USB audio channels (32-bit samples) or up to 48x48 using 24-bit samples.  And even at max channel count you still have 15 processing cores for DSP if needed.  Amazing.

There's MCLK, BCLK and WCLK signals (the I2S clocks) as well as four ADC data wires and four DAC data wires.  Each data wire can support 2 (stereo), 4, or 8 sample slots per wire (time division multiplexed and supported by many higher channel count DACs/ADCs/CODECs) - this as well as sample rates, USB product/vendor descriptor ID and strings, are all configurable at compile-time.

BTW with OS X and Linux support USB audio 2.0 natively while with Windows you need a third party driver (figures).
Title: Re: Audio Effects DSP Board
Post by: glennalday on April 26, 2017, 11:24:57 PM
Question:
How was you able to implement the usb bootloader?
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on April 27, 2017, 04:37:54 AM
This seems to fit my needs for a multichannel usb audio interface. Please count me in! I wan't one! :)

Great.  This little board can do up to 32x32 USB audio channels (32-bit samples) or up to 48x48 using 24-bit samples.  And even at max channel count you still have 15 processing cores for DSP if needed.  Amazing.

There's MCLK, BCLK and WCLK signals (the I2S clocks) as well as four ADC data wires and four DAC data wires.  Each data wire can support 2 (stereo), 4, or 8 sample slots per wire (time division multiplexed and supported by many higher channel count DACs/ADCs/CODECs) - this as well as sample rates, USB product/vendor descriptor ID and strings, are all configurable at compile-time.

BTW with OS X and Linux support USB audio 2.0 natively while with Windows you need a third party driver (figures).

Nice to see this progress Mark! Of course I'm in for a board as well.

Question: how much effort is it to incorporate ADAT lightpipe functionality in your framework? Have you considered it? The 4 DAC data wires could be used two drive two toslink receivers and two toslink transmitters, for a total of 16 in/16 out.

Also, I believe this board would be a possibility to test stuff before the guitar adapter board is available: https://www.pjrc.com/store/teensy3_audio.html
Title: Re: Audio Effects DSP Board
Post by: micromegas on April 27, 2017, 10:35:47 AM
This seems to fit my needs for a multichannel usb audio interface. Please count me in! I wan't one! :)

Great.  This little board can do up to 32x32 USB audio channels (32-bit samples) or up to 48x48 using 24-bit samples.  And even at max channel count you still have 15 processing cores for DSP if needed.  Amazing.

There's MCLK, BCLK and WCLK signals (the I2S clocks) as well as four ADC data wires and four DAC data wires.  Each data wire can support 2 (stereo), 4, or 8 sample slots per wire (time division multiplexed and supported by many higher channel count DACs/ADCs/CODECs) - this as well as sample rates, USB product/vendor descriptor ID and strings, are all configurable at compile-time.

BTW with OS X and Linux support USB audio 2.0 natively while with Windows you need a third party driver (figures).

Nice to see this progress Mark! Of course I'm in for a board as well.

Question: how much effort is it to incorporate ADAT lightpipe functionality in your framework? Have you considered it? The 4 DAC data wires could be used two drive two toslink receivers and two toslink transmitters, for a total of 16 in/16 out.

Also, I believe this board would be a possibility to test stuff before the guitar adapter board is available: https://www.pjrc.com/store/teensy3_audio.html
I've use the Teensy's audio adaptor quite a lot. It is good, but you would still need some signal conditioning for input & output (an option is to use Piotr's IO board: http://www.hexeguitar.com/diy/utility/devloop). Another one that has been there for a while is Mikroe's WM8731 board.
Title: Re: Audio Effects DSP Board
Post by: markseel on April 27, 2017, 11:17:04 AM
Question: how much effort is it to incorporate ADAT lightpipe functionality in your framework? Have you considered it? The 4 DAC data wires could be used two drive two toslink receivers and two toslink transmitters, for a total of 16 in/16 out.

OK that's an interesting thought.  I've already coded ADAT and SPDIF for XMOS so adding output capability to this audio/effects development kit would be trivial.  I also have code for ADAT and SPDIF input but only for the wire protocol - not for the clock recovery aspect in which you'd use the SYNC info in the protocol(s) along with a PLL (configured via I2C) to generate a recovered bit clock.  But that's certainly doable if there's enough interest :-)

Also, I believe this board would be a possibility to test stuff before the guitar adapter board is available: https://www.pjrc.com/store/teensy3_audio.html

Good idea.  That board would hook right up to the I2C and I2S signals.  It would be straightforward to port over the CODEC configuration code that uses I2C).  The only missing piece is a 3.3V supply but the board has 5V so I guess you'd just have to add a 5V to 3.3 regulator.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on April 29, 2017, 08:55:10 AM
Question: how much effort is it to incorporate ADAT lightpipe functionality in your framework? Have you considered it? The 4 DAC data wires could be used two drive two toslink receivers and two toslink transmitters, for a total of 16 in/16 out.

OK that's an interesting thought.  I've already coded ADAT and SPDIF for XMOS so adding output capability to this audio/effects development kit would be trivial.
Good to hear,
Quote
I also have code for ADAT and SPDIF input but only for the wire protocol - not for the clock recovery aspect in which you'd use the SYNC info in the protocol(s) along with a PLL (configured via I2C) to generate a recovered bit clock.
... but you lost me here :)

Quote
But that's certainly doable if there's enough interest :-)
There might be, once people realize that the Behringer ADA8000 provides 8in/8out for a ridiculously low price :)
Behringer gets a lot of crap, much of it deserved, but the mic pres in the ADA8000 are actually very good designs.

Also, I believe this board would be a possibility to test stuff before the guitar adapter board is available: https://www.pjrc.com/store/teensy3_audio.html

Good idea.  That board would hook right up to the I2C and I2S signals.  It would be straightforward to port over the CODEC configuration code that uses I2C). 
[/quote]
I assume that's just a matter of sending the right initialization commands, datasheet in hand.
Title: Re: Audio Effects DSP Board
Post by: peterv999 on May 01, 2017, 11:54:27 AM
Please count me in Mark for one!

Great project!

Piet
Title: Re: Audio Effects DSP Board
Post by: Tuff Pedals on May 09, 2017, 12:36:39 PM
Hi Mark,

Fantastic project , please count me in for a board.

Cheers daz
Title: Re: Audio Effects DSP Board
Post by: tcpoint on May 09, 2017, 12:56:45 PM
Put me down for a board.  I appreciate all the work.
Title: Re: Audio Effects DSP Board
Post by: markseel on May 09, 2017, 02:26:02 PM
I am definitely interested in one
Definitely like to have one! though I'm not familiar with coding stuff.
How many IRs it can hold at once?
I need a small Cabsim board inside of my DIY preamp pedal.
I'd also be interested in a board when the time comes along, although I'm still a bit wary of construction complexity and screwing up something expensive while trying to DIY. Which is to say that I'm a bit price-sensitive, but following the development with great interest 8) A Kickstarter or something as mentioned earlier in the thread sounds like a reasonable approach to me.
This seems to fit my needs for a multichannel usb audio interface. Please count me in! I wan't one! :)
Nice to see this progress Mark! Of course I'm in for a board as well.
Please count me in Mark for one!
Fantastic project , please count me in for a board.
Put me down for a board.  I appreciate all the work.

Thanks for the interest everyone.  Some unanswered questions from previous posts:

1) Regarding using a CODEC: "I assume that's just a matter of sending the right initialization commands, datasheet in hand."

Right, the development kit has I2S functions you can call.  The FlexFX firmware will call callback functions for events like volume changes from USB, sample-rate changes from USB, a timer, etc.  You can add your I2C code to these callbacks to manage the CODEC's behavior/settings appropriately.

2) How was you able to implement the usb boot loader?

The XMOS chip has a ROM boot loader that loads the FlexFX firmware from its internal FLASH memory.  This firmware in FLASH memory can be upgraded at any time via USB MIDI.

3) How many IRs it can hold at once?

The XEF232 has 2MB of FLASH of which less than 1MB is program code.  So there will be at least 1MB for data (like IR data).  For a decent size IR (80 msec at 48k with 32-bit samples) one IR would consume a bit less than 16KB.  So that would be 68 IR's.

4) Audio board support?

A companion board is being designed now that has a CS4270 audio CODEC with stereo line-in and line-out connections, a 9V to 5V linear voltage regulator for powering the system from 9V, and some signal conditions for guitar inputs as the alternative input (rather than line-in) that can be selected via a couple of jumpers.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on May 09, 2017, 04:24:52 PM
Lately I've been playing a bit with jQuery knobs and WebMIDI. It's definitely possible to make a web-based mixer UI, running in the browser, that sends (SysEx) commands to a USB-MIDI device. See screenshot here: https://www.dropbox.com/s/e60tqgpv1oo1xa9/webmidi.png?dl=0
This simple example shows four channel strips with each four EQ bands, a panpot and four output busses.

I have also tested this page with a real USB-MIDI thingy, hardware looped-back from out back to the in with a MIDI cable, and all commands bounce back nicely. Next thing to implement are shelving EQs and what not, and include the calculations to convert EQ-settings to biquads. (which other people have done before me, for example http://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/ and the therein linked .js file)

I find this webbased way of working very effective in that you can create a decent UI real quickly, is platform-independent, no drivers needed, etc.

Just thinking out loud: another possibility might be to link a RasPi Zero or maybe even an ESP chip to the FlexFX board (UART), which then can serve a page and calculate biquads and pass them to the FlexFX.

With your framework, the possibilities seem endless.
Title: Re: Audio Effects DSP Board
Post by: markseel on May 09, 2017, 04:29:55 PM
That's really cool - I would love to be able to control this via MIDI using a GUI running in a browser.  Is it possible to do this?  Sounds like it if I understood you correctly.  Does that WebMIDI support MIDI in both directions?

Yeah I thought about using an RasPi via USB and briefly looked around at RasPi MIDI host support but I wasn't convinced that this would be easy.  So MIDI over UART would be the way to go I guess.

But I'd be more interested in the WebMIDI route if I could send MIDI to the FlexFX board and receive MIDI from it as well.  I'm going to look into that!

Also saw this which looks interesting: https://www.midi.org/specifications/item/bluetooth-le-midi
Title: Re: Audio Effects DSP Board
Post by: orbitbot on May 09, 2017, 05:26:36 PM
Looking at the spec WebMidi seems to be Chrome-only, but should support MIDI in both directions. Most of the WebAudio stuff has been implemented a few years back, so I guess the functionality in general should be pretty comprehensive, but haven't had time to check out any implementation details yet.

Spec is here if you have time on your hands or know what to search for in particular: https://webaudio.github.io/web-midi-api/
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on May 10, 2017, 02:27:20 AM
Indeed, it works both ways. You add an event handler to any type of message you wish to process. In the code below it's processed by an unnamed inline function.

It's supposed to work in other major browsers with a plugin.

Code: [Select]
// jQuery handler for changes in the UI
$( ".knob-values" ).on( "knobnewvalue", function(a,b,c) {
    console.log(   $(this).parent().parent().parent().attr("id") + "/"
                 + $(this).parent().parent().attr("class") + "/"
                 + $(this).parent().attr("knob")
                 + ": " + $(this).val() );
    if(midi) output.playNote("A1",1);
});

var output;
var input;
var midi = false; // to prevent errors when there's nothing connected

WebMidi.enable(function (err) {
  if (err) {
           console.log("WebMidi could not be enabled.");
  } else {
  // Show available inputs and outputs
  console.log(WebMidi.inputs);
  console.log(WebMidi.outputs);
  // Retrieving an output port/device using its name
  output = WebMidi.getOutputByName("Scarlett 2i4 USB");
  input = WebMidi.getInputByName("Scarlett 2i4 USB");
  midi = true;
  try {
input.addListener('noteon', "all",
    function (e) {
    console.log("Received 'noteon' message (" + e.note.name + e.note.octave + ").");
    });
  } catch(err) { midi = false; };
  }
},true);
Title: Re: Audio Effects DSP Board
Post by: markseel on May 12, 2017, 10:34:16 AM
Very cool.  A FlexFX controller, display, and uploader running in Chrome.  Check these out:

http://wiki.lividinstruments.com/wiki/Bluetooth_LE_MIDI_Connection
http://community.silabs.com/t5/Bluetooth-Wi-Fi-Knowledge-Base/Midi-over-BLE/ta-p/170804
https://www.midi.org/specifications/item/bluetooth-le-midi

So control could be wireless too and BLE MIDI is supported by lots of platforms already.
Title: Re: Audio Effects DSP Board
Post by: mhelin on May 12, 2017, 12:12:07 PM
Get this:
http://www.ebay.com/itm/New-NRF51822-BLE4-0-Bluetooth-2-4GHz-Wireless-Module-Board-Core51822-B-/292006080825

and use this software:
https://github.com/sieren/blidino/tree/master/nRF51822-BLEMIDI

Works on Arduino, maybe not too difficult to port to xCORE platform.

nRF51822 SoC includes Cortex-M0 core, maybe the BLE-MIDI stack could run on the chip instead of xCORE.

nRF5 is supported by MBED so it might be easiest that way:
https://developer.mbed.org/teams/Bluetooth-Low-Energy/

See also this:
http://redbearlab.com/blenano/
Title: Re: Audio Effects DSP Board
Post by: markseel on May 12, 2017, 12:27:57 PM
Bingo!  I'm going to get one  :D
Title: Re: Audio Effects DSP Board
Post by: mhelin on May 12, 2017, 12:51:04 PM
There are plenty of those three dollar nRF51822 boards available, the one I linked above doesn't seem to have integrated antenna. Wonder which of those is the best design. Some other ones have the antenna on the PCB but not so many I/O's, probably just some serial interface.

This one comes from Hong Kong meaning you will get it faster, and it has plenty of pins and the antenna:
http://www.ebay.com/itm/5Pcs-Low-Power-Consumption-BLE4-0-Bluetooth-L-2-4-GHz-Wireless-Module-NRF51822-/272488822710

This is cheaper but has only few IO pins.
http://www.ebay.com/itm/5Pcs-Module-Ttl-Nrf51822-04-Ble4-0-3-3V-Wireless-Bluetooth-Low-Power-Consumpti-X/232323375871

Title: Re: Audio Effects DSP Board
Post by: markseel on May 12, 2017, 12:56:23 PM
Right now I'm thinking all I want is a BLE-MIDI to/from MIDI-UART bridge.  So just a couple of I/O's for UART TX/RX would be enough ... I think.

Then I could use the FlexFX UART TX/RX MIDI interface as-is and the BLE transport would be transparent - FlexFX wouldn't know if it's a wired or wireless MIDI interface.
Title: Re: Audio Effects DSP Board
Post by: mhelin on May 16, 2017, 07:43:44 AM
This one also from HK is smaller and apparently copy of another board:

Ebay:
http://www.ebay.co.uk/itm/292114800361

Orig with documentation:
http://www.wireless-tag.com/index.php/Product/dis/26.html
Title: Re: Audio Effects DSP Board
Post by: markseel on May 30, 2017, 10:25:13 PM
Hey all - it's been a while since I posted an update, and also I'd like some input ...

The board (I have three prototypes) works great so far and other than an error on the 1.0V switching regulator resistor divider (that sets the output voltage).  Simple enough to fix with my rework station so I'm calling the FlexFX board done and ready for a small production run (perhaps via KickStarter).

I want to supply a mother board of sorts that the FlexFX plugs into.  This board provides analog input and output and a guitar interface (1/4" jacks), three rotary encoders (with push buttons) for parameter control, and a foot-switch hookup for stomp-box usage.  It also provides one of the two below:

1) A 5 digit seven-segment LED display to show preset/memory selection, parameter selection, and parameter values.
2) A Bluetooth LE module that exposes a BLE service that indicates preset/memory selection, parameter selection, and parameter values.  Would then profile a simple app for iPhone, and maybe other platforms.

I'm also designing a milled aluminum case to be offered as incentive during the KickStarter campaign.  Of course #1 and #2 have slightly different case requirements.

I can only do one of these for now.  #1 is pretty standard but with just 5 numerical digits the navigation of parameters and setting values might be a bit cumbersome.  #2 requires that an iPhone, Android phone, or computer (maybe even a browser?) is used as the display device but this approach has many more possibilities then the LED display.

Thoughts?
Title: Re: Audio Effects DSP Board
Post by: glennalday on May 30, 2017, 10:37:36 PM
How about an OLED display? or a 16x4 LCD module? You can display more information using it than a 7segment LED.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on May 31, 2017, 02:21:11 AM
Since you're asking, I'd prefer to keep it simple and focus on the foundation. You'll probably be busy enough as it is  :icon_wink:

That said, if a 5 segment 7 digit is a possible, a serial 16x4 lcd should be comparable in complexity but add more flexibility?
Title: Re: Audio Effects DSP Board
Post by: orbitbot on May 31, 2017, 04:43:02 AM
The way I see it, the options presented are not really at the same level, unless in the BT case you would be able to also relatively easily use an external display (perhaps with an additional blue pill/arduino to drive a display of choice). The BT solution sounds really interesting, but I'm not sure how practical it is to always be required to have a secondary device in use to get any interaction feedback. Conceptually it seems to be quite restrictive at first thought.
Title: Re: Audio Effects DSP Board
Post by: briandress on June 12, 2017, 07:47:00 PM
Is this still happening?
Title: Re: Audio Effects DSP Board
Post by: skraninger on June 17, 2017, 12:56:45 PM
I have a number of axoloti boards.  STM based audio device with a great programming environment.
Check it out.  If a similar environment is possible for this board, it would be very powerful.
I am very interested in this board, and would probably purchase more than one when available.
I have an xmos startkit with audio board and have tried a couple things with it.
The only thing I would request is additional ram for longer delay/looping capability.  Is this difficult?
This looks to be a great dsp board when it becomes available, thanks.
Title: Re: Audio Effects DSP Board
Post by: markseel on June 17, 2017, 04:54:42 PM
Hi skraninger.  I'm really glad you're interested in the board  :D

I've seen the Axoloti software and it looks cool.  If *anyone* ever wanted to do something like that for this board I'd be more than happy to provide the needed XMOS firmware to make that work.

An update for this project; I'm working on the MIDI data flow and firmware upgrade support (via MIDI) so folks can build their own effects and upload using USB/MIDI.  An example project doing cab simulation using IR data is almost done.  Stay tuned - a Kick Starter campaign will start soon.
Title: Re: Audio Effects DSP Board
Post by: Digital Larry on June 18, 2017, 10:58:44 AM
It's not been widely advertised but SparkFun has come up with a Teensy-based effects pedal for which someone developed a graphical UI to create DSP code.  See:  https://www.pjrc.com/teensy/gui/

I created a Java program that provides a GUI for FV-1 code.  I wrote all the GUI code and it was a massive undertaking.  However, the Sparkfun tool leverages the "node-red" networking application GUI, which is open source.

I haven't looked closely at the Sparkfun thing but I think it generates C code which you have to put a little extra effort into in order for it to work with whatever chip/compiler you are using.  It's possible that some of this might translate directly to this Xmos chip (portable C code).  The main reason I bring this up is that if *someone* wants to write a tool specifically for this Xmos platform I would really suggest leveraging something like node-red to start with so you can focus on the platform specific stuff.
Title: Re: Audio Effects DSP Board
Post by: markseel on June 27, 2017, 04:22:36 PM
Sorry - I'm confused.  :)  What did I miss?
Title: Re: Audio Effects DSP Board
Post by: micromegas on June 27, 2017, 06:56:13 PM
it's a bot. Try searching in google for a piece of the text. I just reported it.

Thanks to the admins for getting rid of the bot :)
Title: Re: Audio Effects DSP Board
Post by: markseel on September 11, 2017, 04:05:16 PM
Haven't posted an update in a while so here's one ...

(https://s26.postimg.org/gfk76441x/test.jpg) (https://postimg.org/image/gfk76441x/)

The board on the left is the FlexFX board that supports USB audio class 2.0, USB MIDI, multi-channel I2S, DSP processing, and I2C control of peripherals.

The board on the right is a support/test/example board of sorts that it plugs into that provides the audio ADC/DAC, guitar input, line out, EEPROM storage, 4 channel ADC for sensing pots, 3 pots, and two stereo jacks.

The DSP board can be programmed (uses an XMOS XEF232) by using the XMOS compiler and my FlexFX framework that provides all of the USB/I2S/MIDI/I2C functions - so you just add your DSP algorithms, your MIDI handling code for handling data loading and control, and your I2C control code for sensing pots and  controlling displays.

I have a sample application (free to use and serves as a programming example) for stereo IR processing (e.g. speaker cab sim) which is up and running -- will update GitHub with that soon.

I can load IR's (in .wav file format) over USB using a Python script - it takes less than one second to load an IR.

For test I ran my overdrive/distortion effects pedal into this board with the board sending the simulated speaker audio (mixed with USB audio for fun) to a pair of Presonus powered monitors.  Sounds great!

BTW I bought a bunch of IR's for Celestion speakers directly from Celestion - very reasonable price!

Ready to KickStart this now  :icon_biggrin:

 
Title: Re: Audio Effects DSP Board
Post by: tcpoint on September 11, 2017, 04:24:33 PM
Great news.  I'm in.
Title: Re: Audio Effects DSP Board
Post by: micromegas on September 12, 2017, 04:23:29 AM
Nice! I am definitely in for one!
Title: Re: Audio Effects DSP Board
Post by: cliffsp8 on September 12, 2017, 01:14:27 PM
Excellent! I'll be interested in this kickstart.

Just to be clear, does your framework run under Windows and load the complied code via USB into the FX board? In the photo there is another module plugged into the USB port on the FX board. I'm guessing that is not part of the final unit?

regards

Cliff
Title: Re: Audio Effects DSP Board
Post by: cliffsp8 on September 12, 2017, 01:37:33 PM
I see that the the additional board is the JTAG board (14.75 from Farnell in UK). So to rephrase my question, is this necessary for putting the code into the FX board or can it be programmed directly via the USB?

regards

Cliff
Title: Re: Audio Effects DSP Board
Post by: markseel on September 12, 2017, 02:25:39 PM
Good question ...

1) Source code is compiled and linked using the XMOS toolchain (free download).
2) The XMOS toolchain can burn the firmware image to the XEF232 internal flash via the JTAG board.
3) The JTAG board has a 2x10 0.10" header while the FlexFX board has a 2x5 0.05" header.  I have an adapter board (as seen) that will ship (ribbon cable included) with the FlexFX board.
4) The final board will support firmware upgrades via USB.  This isn't done yet - the current board has a design flaw that prevents this.  But the next board rev should fix it.
Title: Re: Audio Effects DSP Board
Post by: cliffsp8 on September 12, 2017, 02:58:46 PM
Thanks for the clarification Mark.

I'm looking forward to the kickstart.

Cliff
Title: Re: Audio Effects DSP Board
Post by: markseel on September 13, 2017, 10:51:54 AM
Here's some specs ...

FlexFX DSP Board

1 - Uses the XEF232 32-core processor
2 - 2000 MIPs, four 500 MHz tiles each with single-cycle 64-bit MAC
3 - USB powered or external power via jumper
4 - 17-pin 0.1" header for 5V, ground, I2C SDA/SCL, UART TX/RX, I2S MCLK/BCLK/WCLK, 4 I2S SDIN and 4 I2S SDOUT pins (up to 32x32 channels in/out using I8S TDM)
5 - Contains processor, 1V switching supply, 3.3V LDO, oscillator, power/reset supervisor, and USB jack

FlexFX Software Kit

1 - USB Audio Class 2.0, 2x2 channels in/out, up to channels 32/32 in/out
2 - USB MIDI
3 - 15 DSP threads (to execute your custom code) with 100 MIPs each
4 - Handles routing of MIDI and audio between USB, I2S, and DSP threads
5 - DSP support functions for 64-bit fixed point, FIR and IIR filters
6 - I2C and UART interfaces
7 - I2S interface, up to 768 kHz sample rate (stereo), up to 8 TDM channels per SDIN/SDOUT pin (48 kHz)
8 - Input to output total group delay (i.e. latency) of 11 samples

FlexFX Demo Board

1 - Header for 8 10-bit ADC inputs, stereo audio in and out, pushbutton/foot-switch and LED
2 - AK4420 DAC, 105dB dynamic range, up to 192 kHz Fs, 19.3 sample group delay
3 - AK5386 ADC, 110dB dynamic range, up to 192 kHz Fs, 29.4 sample group delay
4 - Guitar input buffer, mono pseudo-differential or single-ended stereo
5 - Two AD7995 four-input I2S 10-bit ADC's
6 - One M24M02 2Mbit (256 Kbyte) I2C EEPROM
7 - Powered from 5V (on board 3.3V LDO)

FlexFX Cabsim Example

1 - Stereo IR processing at 48 kHz, USB audio input and output at 48 kHz
2 - Mono guitar input and stereo line-level output (using the demo board)
3 - Supports IR lengths of up to 4500 samples (93.75 msec)
4 - IR's can be loaded via USB to DSP threads or burned to EEPROM
5 - IR's can be loaded from EEPROM to DSP threads
6 - Pot 1 selects the IR pair (left and right) to load from EERPOM
7 - Pot 2 adjusts output volume (uses digital volume via truncation/dithering)
8 - Pot 3 adjusts USB audio and Cabsim output mix/blend
9 - Python script for loading IR's in WAVE file format over USB
Title: Re: Audio Effects DSP Board
Post by: bardoik on September 14, 2017, 06:03:43 AM
There are plenty of those three dollar nRF51822 boards available, the one I linked above doesn't seem to have integrated antenna. Wonder which of those is the best design. Some other ones have the antenna on the PCB but not so many I/O's, probably just some serial interface.

This one comes from Hong Kong meaning you will get it faster, and it has plenty of pins and the antenna:
http://www.ebay.com/itm/5Pcs-Low-Power-Consumption-BLE4-0-Bluetooth-L-2-4-GHz-Wireless-Module-NRF51822-/272488822710

This is cheaper but has only few IO pins.
http://www.ebay.com/itm/5Pcs-Module-Ttl-Nrf51822-04-Ble4-0-3-3V-Wireless-Bluetooth-Low-Power-Consumpti-X/232323375871


I think that the first have better design
Title: Re: Audio Effects DSP Board
Post by: 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.

(https://s26.postimg.org/abmx6ygjp/minifx.png) (https://postimg.org/image/abmx6ygjp/) (https://s26.postimg.org/ae6stsk79/minifx2.png) (https://postimg.org/image/ae6stsk79/)

MiniFX DSP Board (1.4" x 1.0")

1 - Uses the XUF216 32-core processor
2 - 1000 MIPs, two 500 MHz tiles each with single-cycle 64-bit MAC
3 - USB powered or external power via zero-ohm resister placement/removal
4 - 2x9-pin 0.1" header for 5V, ground, I2C SDA/SCL, UART TX/RX, I2S MCLK/BCLK/WCLK, 4 I2S SDIN and 4 I2S SDOUT pins (up to 32x32 channels in/out using I8S TDM)
5 - Contains processor, 1V switching supply, 3.3V LDO, oscillator, power/reset supervisor, and USB jack

The MiniFX and the FlexFX boards have the same features and both use the same development kit and JTAG hardware.  They also have the same signals brought out to the pins (UART, I2C, I2S, GND, 5V).

The MiniFX has five 100-MIP cores for DSP while the FlexFX has fifteen 100-MIP cores for DSP.  The MiniFX is still really powerful for its size and can perform 64 msec mono or 32 msec stereo IR processing/convolution at 48 kHz.
Title: Re: Audio Effects DSP Board
Post by: cliffsp8 on September 19, 2017, 04:42:01 PM
That's a nice surprise  8)

Will you be making the FlexFX demo board available with it?

Cliff
Title: Re: Audio Effects DSP Board
Post by: markseel on September 19, 2017, 05:27:55 PM
Yeah I'm going to update the demo board to accept both boards.
Title: Re: Audio Effects DSP Board
Post by: markseel on October 06, 2017, 03:12:06 PM
Still finalizing the smaller FlexFX board but I did update the Github repo for the SDK.

https://github.com/markseel/flexfx_kit

Check out the README for an overview of FlexFX and a couple of example apps (including a cabsim example). 
Comments/suggestions welcome :-)
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on October 06, 2017, 03:56:49 PM
Looks like Santa's early this year  :icon_biggrin:

Is it possible to have the MiniFX pre-flashed so the JTAG board is not needed and one can start flashing via USB rightaway?
Title: Re: Audio Effects DSP Board
Post by: markseel on October 06, 2017, 04:03:28 PM
Yes - boards will be pre-programmed with FW that supports firmware update via USB MIDI and that passes audio with no DSP.
Title: Re: Audio Effects DSP Board
Post by: MetalGuy on October 06, 2017, 04:20:16 PM
As an end user of a product like this who doesn't know any coding (and I doesn't want to know) I'm interested how easy I would be able to load several IR's and do 3 to 5 effects in a row?
Also maybe at the expense of some functionality can this board be made to play longer IR's like 500msec for example?
Title: Re: Audio Effects DSP Board
Post by: markseel on October 06, 2017, 04:38:35 PM
Each 100 MIP core can do perhaps 13 msec if IR using FIR convolution.  So the small board can support around 32 msec of stereo IR and 64 msec of mono IR (at 48 kHz sample rate).  The large board would up those figures by x3 ... so maybe 96 msec and 192 msec respectively.  We couldn't get 500 msec without resorting to a different convolution approach (i.e. frequency domain).

 
Title: Re: Audio Effects DSP Board
Post by: markseel on October 08, 2017, 01:59:16 PM
I added SPDIF output and ADAT output support to the FlexFX SDK (48 kHz Fs only for now).  I'm curious; anyone considering using these or willing to help test?
Title: Re: Audio Effects DSP Board
Post by: MetalGuy on October 08, 2017, 04:15:09 PM
I could be interested as an end user in getting one that can do longer IR's and if it comes with some user friendly software.
Title: Re: Audio Effects DSP Board
Post by: markseel on October 08, 2017, 06:39:39 PM
These boards are intended to support DIY'ers and folks who want to learn DSP and/or make their own products.  I'll provide boards, example code, scripts, and support but that's about it as far as this kit goes.

You may want to consider the AMT Pangaea CP-16M although it's only 20.5 msec of mono IR and seems expensive at $75.

Or just get the Digitech CabDryVR pedal (Stereo 44.1 kHz but no mention of IR turncation/length *anywhare*  :icon_eek:).  Is the name of that pedal really lame or is it just me?  :icon_lol:  I don't think you can load your own IR's though - not really sure.

Keep in mind that even the AxeFX normal-res IR length is 20 msec.  Hi-res is 40 and ultra-res is 170 msec.  So 64 msec mono and 32 msec for stereo on a $50 or so FlexFx board is doing pretty good.

I'll have a Cabsim/IR pedal with a nice user interface released under the BitStream Audio name in the future but it would be a final product and not really a dev kit ... and therefore the price would reflect that I suppose.
Title: Re: Audio Effects DSP Board
Post by: markseel on October 08, 2017, 06:50:47 PM
Fractal Audio has fantastic documentation on their effects.  Here's info in IR's:

https://www.google.com/search?q=wiki+fractal+audio+impulse+responses&oq=wiki+fractal+audio+impulse+responses
Title: Re: Audio Effects DSP Board
Post by: MetalGuy on October 09, 2017, 03:56:36 AM
Thanks for the info. I've researched all that thoroughly and I have the AMT CP-16 module which does mono in - stereo out.
However I was wondering why even expensive products like AXE or Torpedo don't do more than 20 msec while Lodigy's EPSi does up to 1.5sec. Below is a gutshot of the EPSi, maybe you can give us some comments how it's done.

DSP - ADSP21357
RAM - 48LC2M32B2

(https://s1.postimg.org/4kf9gxxemz/image.jpg) (https://postimg.org/image/4kf9gxxemz/)
Title: Re: Audio Effects DSP Board
Post by: markseel on October 09, 2017, 02:13:06 PM
Good point and question MetalGuy.  It comes down to the intention of convolution and the method by which it's performed.

For convolution applied to close-mic'd cab sim the reverberation times are generally short - on the order of 20msec (small cab, close mic) to perhaps 150 msec (big cab, open back?) but it depends on the cab/speaker being used.  For convolution applied to modeling room dynamics or performing convolution-based reverb modeling (of spring reverb, plate reverb, room reverb) the IR will be much longer - perhaps seconds.

There's two fundamental ways to perform convolution.

The direct method is just the application of time-domain convolution (like an FIR) whereas the frequency domain method is the application of FFT's.  The direct method is very straight-forward to implement and is suitable for the shorter IR's (cab sims) but it becomes too CPU intensive at long IR lengths.

The frequency domain methods are more complicated to code but due to the complexity growth rate of time domain convolution for longer IR's they're the only way to achieve long convolution with reasonable hardware. A downside is that the use of frequency domain convolution implies block-level processing due to the application of FFT's - and block processing adds latency.  But ... there's lots of papers on low or zero latency FFT convolution.

https://www.google.com/search?q=fft+convolution+latency&oq=fft+convolution+latency

The EPSi by Logidy is a beast and Olivier (the dude who owns Logidy and who is a DSP and Analog Devices expert) could comment on the frequency domain approach with authority but I'd guess that the low/zero-latency approaches outlined in these papers was used.  There's enough RAM in the EPSi for well over 5 seconds of 48kHz sample delay so the question becomes whether or not a DSP/CPU has the power to implement the required overlapped FFT algorithms to accomplish some reverb duration or IR convolution length of interest.

I'm not sure what an XMOS tile can do as far as processing bandwidth for overlapped frequency domain convolution but it does have enough RAM for just over 1 second of reverb or IR length at 48 kHz.  I used the time-domain approach for my cabsim / IR processor and the CPU/DSP power is the limiting factor there.  Maybe I should look into the other method?  :)

I don't know how AxeFX performs convolution but I'd guess that for the 20ms and 40ms lengths it uses direct convolution (time domain) and then uses frequency domain or a combination of the two for the 170 msec.  As the AxeFX wiki states there's typically not much IR energy beyond 100 msec and often not even beyond 20 or 40 msec in the context of cab sim and speaker sim applications.  So whether or not you need longer IR support (over 100 msec) will depend on the cab being simulated.  And whether or not you need really long IR support (100's of msec up to seconds) will depend on what your trying to model (cab-sim vs room dynamics vs reverberation modeling). 

So FlexFX is intended to perform IR's on cab/speaker responses.  AxeFX 20/40 msec ... same.  AxeFX 150 msec?  ... Cab and speaker sim I suppose (most commercial cab sim IR's are over 150 msec even though there's almost always negligible energy beyond 80 or 100 msec).  The EPSi would be used to simulate reverb systems and room/hall acoustics and far-mic'd cabs in various environments.

Hope that helps!

Title: Re: Audio Effects DSP Board
Post by: MetalGuy on October 09, 2017, 03:57:36 PM
Thanks for your detailed explanation! It was interesting for me to learn more about this.
Title: Re: Audio Effects DSP Board
Post by: cliffsp8 on October 10, 2017, 07:03:52 PM
Re SPDIF and ADAT, I connect an 8 channel mic pre unit to an RME interface using ADAT.

I hadn't considered using DSP with ADAT but I'm happy to take part in testing if it will help. I use optical cables to connect between the two units.

The RME also has SPDIF on RCA connector. Will yours want to be clock master or slave?

Cliff
Title: Re: Audio Effects DSP Board
Post by: markseel on October 11, 2017, 11:29:48 AM
Thanks for the offer cliffsp8.  I was thinking some folks may want to use the multi-channel USB interface to bridge to SPDIF or 8-channel ADAT.  FlexFX has to be the clock master unless I add a PLL to recover the master audio clock from the WCLK - that's not hard to do though and could be added to the demo board that has the socket for the FlexFX module.  So if you're up to that I'll send you a module for free :-)  Hmm to actually test this I'd have to make a board with proper coax/optical interfaces.  Will have to look into that so these features may take a while to implement.  But I do think the USB/SPDIF/ADAT bridging may be interesting.  BTW I've also worked with XMOS AVB (i.e. mutli-channel time synchronized audio over ethernet) so that may also be a feature set addition someday.  Then one could bridge mutli-channel USB audio to AVB to ADAT or SPDIF, or make AVB peripherals and also do some DSP.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on October 11, 2017, 02:00:40 PM
I also own a 8-channel mic pre/line out (so 8 in/8 out) and am willing to test for you. I'm able to design and etch (or order in case of double sided designs) my own (optical interface) boards, but I need help with the MiniFX firmware part so I would be very grateful if you're going to handle that part.

I don't need a module for free, happily willing to buy one from you :D
Title: Re: Audio Effects DSP Board
Post by: mhelin on October 11, 2017, 04:05:49 PM
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.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on October 18, 2017, 05:56:44 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)?
Title: Re: Audio Effects DSP Board
Post by: micromegas on October 19, 2017, 01:10:56 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.
Title: Re: Audio Effects DSP Board
Post by: markseel on October 19, 2017, 04:00:33 PM
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.
Title: Re: Audio Effects DSP Board
Post by: markseel on November 02, 2017, 04:12:17 PM
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:
Title: Re: Audio Effects DSP Board
Post by: Tuff Pedals on November 03, 2017, 11:04:27 AM
Count me in  :icon_razz:
Title: Re: Audio Effects DSP Board
Post by: micromegas on November 04, 2017, 05:33:07 AM
Count me in as well. Can't wait to give it a try
Title: Re: Audio Effects DSP Board
Post by: tcpoint on November 04, 2017, 11:03:31 PM
Count me in.
Title: Re: Audio Effects DSP Board
Post by: cliffsp8 on November 05, 2017, 02:02:48 PM
Count me in too. And please keep me informed about the ADAT option if you still want me to test it.

Cliff
Title: Re: Audio Effects DSP Board
Post by: markseel on November 13, 2017, 07:42:04 PM
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.

(https://s18.postimg.org/5x53nczv9/demo.jpg) (https://postimg.org/image/5x53nczv9/)

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.
Title: Re: Audio Effects DSP Board
Post by: markseel on November 13, 2017, 11:17:11 PM
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
Title: Re: Audio Effects DSP Board
Post by: markseel on November 16, 2017, 10:40:05 AM
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.

Code: [Select]
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 (https://raw.githubusercontent.com/markseel/flexfx_kit/master/flexfx.py.usage2.mp4)

Code: [Select]
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]);
}

Title: Re: Audio Effects DSP Board
Post by: markseel on November 18, 2017, 01:09:19 PM
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 (https://raw.githubusercontent.com/markseel/flexfx_kit/master/app_cabsim.mp4)
Title: Re: Audio Effects DSP Board
Post by: markseel on November 19, 2017, 11:25:53 PM
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 (https://raw.githubusercontent.com/markseel/flexfx_kit/master/app_chorus.mp4)
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 23, 2017, 02:57:05 PM
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!
(https://s18.postimg.org/6513jlgol/reaper_plus_osc_plus_flexfx_equals_win.png) (https://postimg.org/image/6513jlgol/)

Code: [Select]
"""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()
Title: Re: Audio Effects DSP Board
Post by: markseel on November 23, 2017, 03:39:06 PM
Nice work!  How many audio channels were you thinking of using?  I'll make a high channel-count mixer example.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 23, 2017, 03:54:01 PM
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.
Title: Re: Audio Effects DSP Board
Post by: markseel on November 23, 2017, 04:09:02 PM
ADAT out from the FlexFX or ADAT input to the FlexFX?
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 23, 2017, 04:13:14 PM
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.
Title: Re: Audio Effects DSP Board
Post by: markseel on November 23, 2017, 04:15:07 PM
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.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 23, 2017, 04:22:06 PM
Yep, one BNC which can be configured to be master or slave:
https://medias.audiofanzine.com/images/normal/behringer-ultragain-pro-8-digital-ada8000-995195.png

It might be that I'm completely misunderstanding this sync-thing though.

Title: Re: Audio Effects DSP Board
Post by: markseel on November 23, 2017, 04:35:56 PM
OK good.  Both ADAT and SPDIF are designed such that some simple logic can be used to sense a run of bits (zero's or one's - can't remember which) that exceeds the same-bit run lengths in the encoded data bitstream.  This pulse can be used as a PLL sync input so that the PLL can lock on to it and multiply it in order to derive the master audio clock.  We'd still have to use a PLL/clock multiplier to derive the 12.288 or 24.576 MHz MCLK but we wouldn't need the additional logic to grab a pulse-train from the actual data bit stream.  XMOS already has code for clock recovery using the Cirrus Logic CS2000 family.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 24, 2017, 03:08:36 AM
I think I understand what you're saying.

If I were to go the codec + preamps route, are there any codecs (or even separate A/D's and D/A's) you recommend? Especially with regards to ease of interfacing (towards the FlexFX I/O, the analog part I can handle). Preferably as easy to solder as is possible! SMD is ok, as long as it's not tooooo small, the bigger the better. Through-hole would be awesome but I've accepted the fact that that's probably not going to be possible.

I also found out that Reaper sends out lots of info over OSC about the tracks etc, whenever you open a project or even switch tabs between projects. So the configuration of the FlexFX mixer could possibly be directed completely by Reaper, with a bit of smart setup of the tracks, names, etc.
Title: Re: Audio Effects DSP Board
Post by: markseel on November 25, 2017, 11:04:44 PM
Yeah I have some ADC/DAC/CODEC favorites :-)  But any one will work as FLexFX supports I2S, LJ PCM, TDM, etc and if there's other I2S variants that need to be supported it's fairly easy for me to add that support and then update GitHub.

I don't like QFN parts since I put boards together by hand for hobby stuff - so I gravitate towards the leaded parts.

The AK4556 is low cost, simple to use, and has decent performance (44k1 to 192 kHz, TSSOP20, 103dB ADC and 106dB DAC dynamic range).  Really pretty good and also the latency is decent (18 samples for ADC, 21 samples for DAC).  No I2C/SPI control port therefore no volume control or other stuff but this keeps things really simple.

The AK4558 is a really nice upgrade (even lower latency, 108 dB dynamic range) but it's QFN.

The AK5386 ADC -- 192 kHz, 110dB dynamic range, TSSOP-16.  Only a handful of passive components needed.  No control port but simple, compact, and very quiet.  Moderately low latency of 16.5 samples.

The AK4420 DAC -- 192 kHz, 105 dB, TSSOP-16, single 5V supply, 19.3 sample latency, super easy to use.  Outputs are ground reference so this makes it even easier to use.

Those are my go to parts.

I've also use the TI PCM5102.  Also super easy to use and it even has a built in PLL that can derive its MCLK from the BCLK or WCLK signals if needed.  Ground referenced outputs, very high dynamic range, up to 384 kHz FS, and low latency.

Since FlexFX supports up to 32 channels and TDM one could use multichannel ADCs/DAC's.  The PCM1681 and AD1934 look interesting although I've never used them.

In all cases I prefer parts that have a HW control option and that don't require I2C or SPI just to keep things simple and to keep the FW agnostic of ADC/DAC/CODEC.  But FlexFX does support I2C so if you want to use part with I2C ports for filter selection, sample rate selection, volume control, etc you can easily do that.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 27, 2017, 12:33:31 PM
I sense an AKM fan here :)

I did a bit more googling into the datasheets of TI, Cirrus and Analog Devices stuff. For higher channel counts it quickly begins to slide towards impractical packages and/or really tiny leads. So for the short term ADAT seems for me the way to go. Or is there a way to multiplex I2S outputs into I8S (TDM) streams? I guess the ADC's need to be clocked in sync for that, one master and multiple slaves or so.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 27, 2017, 12:38:35 PM
Also, what I don't understand is that both devicemakers and interfacemakers only seem to make multichannel products where the number of outputs is *always* higher than the number of inputs. I mean, 6 in/20 out interfaces, who on earth is using that? I just don't understand the market here.

I do understand that outputs are cheaper on silicon than inputs, but has nobody told these guys that they need to listen to their customers? Or is the thinking "outputs are practically free so let's just put them in there so that we seem to be better than the competitors"???
Title: Re: Audio Effects DSP Board
Post by: markseel on November 27, 2017, 05:06:40 PM
Or is there a way to multiplex I2S outputs into I8S (TDM) streams? I guess the ADC's need to be clocked in sync for that, one master and multiple slaves or so.
FlexFX supports 4 sets of I2S, I4S, or I8S input and output wires (four input wires, four output wires, each wire having 2, 4 or 8 channels) all synchronized to BCLK and WCLK.  For multichannel converters and/or multiple stereo converters there's a single set of MCLK, BCLK and WCLK.  For multi-channel converters not using TDM there's of course one SDIN or SDOUT for each pair of analog signals.  TDM lowers the SDIN/SDOUT wire count but finding lower pin-count (TSSOP-20 or 24) eight channel converters looks challenging.  Regardless of multi-channel solution (TDM, no TDM, one IC, multiple IC's) all devices share the clocks (MCLK, BCLK, WCLK) so that data channels and data signals (SDIN or SDOUT) clock edges are synced up.  Note that MCLK is generally used for the DAC/ADC converter's internal processing and I2S related port clock derivation whereas BCLK and WCLK are what SDIN/SDOUT are synced up to.  BCLK and WCLK are provided by FlexFX (FlexFX is the I2S/I4S/I8S clock master) therefore all converters must be used in slave mode.  So FlexFX provides BCLK and WCLK to converters and the master audio oscillator provides the (usually 24.576 Mhz or 22.5792 Mhz) MCLK to FlexFX as well a s all of the converters.
Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 27, 2017, 06:10:43 PM
TDM lowers the SDIN/SDOUT wire count but finding lower pin-count (TSSOP-20 or 24) eight channel converters looks challenging.
True, although I did find LQFP-48 packaged codecs, lead pitch 0.5mm is only slightly narrower than the 0.65mm of TSSOP ;)
[edit] for example the Cirrus Logic CS5368 (which is actually not a codec but only the ADC's) [/edit]

Quote
So FlexFX provides BCLK and MCLK to converters and the master audio oscillator provides the (usually 24.576 Mhz or 22.5792 Mhz) MCLK to FlexFX as well a s all of the converters.

So the FlexFX board doesn't provide a master clock, in your dev-IO-combo it's on the IO-board?
Title: Re: Audio Effects DSP Board
Post by: markseel on November 28, 2017, 10:24:38 AM
There was a typo - corrected it reads: "So FlexFX provides BCLK and WCLK to converters and the master audio oscillator provides the (usually 24.576 Mhz or 22.5792 Mhz) MCLK to FlexFX as well as all of the converters."

"So the FlexFX board doesn't provide a master clock, in your dev-IO-combo it's on the IO-board?"

Correct.  FlexFX and the converters all receive MCLK from the master oscillator.  But, yes, there is a 24.576 MHz oscillator on the demo board that supplies the AK4556 and the FlexFX module with MCLK.  Like this:

Code: [Select]
Module              Demo Board
--------           -------------
   |                     |
   |<-----MCLK-----------+    24.576 Mhz oscillator on demo board (to CODEC and to Module)
   +------BCLK---------->|    To A4556 CODEC on demo board
   +------WCLK---------->|    To A4556 CODEC on demo board
   +------SDOUT[0:3]---->|    To A4556 CODEC (only SDOUT[0])
   |<-----SDIN[0:3]------+    From A4556 CODEC (only SDIN[0])
   |                     |



Title: Re: Audio Effects DSP Board
Post by: pruttelherrie on November 28, 2017, 02:22:29 PM
Clear! Thanks!
Title: Re: Audio Effects DSP Board
Post by: markseel on November 28, 2017, 05:37:32 PM
Here's another example.  From the FlexFX Github README:

Example Application #3 - Overdrive

Overdrive example demonstrating up/down sampling, anti-aliasing filters, and the use of look-up tables and Lagrange interpolation to create a simple preamp model. Up/down sampling by a factor of 2 brings the internal sampling rate to 384 kHz to help manage the aliasing of harmonics created from the nonlinear behavior of the preamp.

https://github.com/markseel/flexfx_kit/blob/master/README.md#example-application-3---overdrive (https://github.com/markseel/flexfx_kit/blob/master/README.md#example-application-3---overdrive)
Title: Re: Audio Effects DSP Board
Post by: markseel on December 06, 2017, 09:39:42 PM
Sorry for the board delays all.

The 50mil 2x5 ribbon cable as the interface between the XTAG and the board had issues.  Turns out that when using the high-speed debug features of XTAG2 the serial data was getting corrupt.  XMOS recommends LVDS when going over 10 cm or so and the ribbon cable and 2x5 connectors were a problem.

So I updated the board to incorporate the 100mil 2x10 header of the XTAG2 to eliminate the ribbon cable so that high-speed debug features work properly.  Now the XTAG2 just plugs into the board(s) directly.  Another delay but it's for the best :-)

I also added a board to the mix - the combo board.  It's the same as the small USB/XMOS digital board except that an audio interface (input buffers/filters, AK4420 DAC and AK5386 ADC) are added on the same board for convenience.

Both boards have the same pinout and dimensions except that the combo board is longer and has extra pins for analog input/output and separate ground/supply if desired. The ADC/DAC on the combo boards is hard-wired to the I2S interface and uses ADC0 and DAC0 signals leaving ADC1/2/3 and DAC1/2/3 available for external parts.  Boards should be back in a couple of weeks.

(https://s17.postimg.org/lojwtk0zv/flexfx_boards.png) (https://postimg.org/image/lojwtk0zv/)