News:

SMF for DIYStompboxes.com!

Main Menu

Audio Effects DSP Board

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

Previous topic - Next topic

markseel

OK - it was missing.  Updated GiTHub.  You should pull down all files just in case.
https://github.com/markseel/FlexFX.git

Digital Larry

Getting closer.  I presume the following indicates that Nirvana is just around the next bend.

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.
Digital Larry
Want to quickly design your own effects patches for the Spin FV-1 DSP chip?
https://github.com/HolyCityAudio/SpinCAD-Designer

markseel

#42
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.

Digital Larry

Digital Larry
Want to quickly design your own effects patches for the Spin FV-1 DSP chip?
https://github.com/HolyCityAudio/SpinCAD-Designer

markseel

#44
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

// ================================================================================================
// "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 );
}

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

Digital Larry

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
Digital Larry
Want to quickly design your own effects patches for the Spin FV-1 DSP chip?
https://github.com/HolyCityAudio/SpinCAD-Designer

wizzgmb

would really like to get one of these to play with

Transmogrifox

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.

Quote from: 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.

On fractional delay interpolation, here is one approach:  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):


//Setup in initialization
     lfoConst =  2.0*M_PI*lfoRate / fS;
     sinPart = 1.0;
     cosPart = 0.0;


        //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".
trans·mog·ri·fy
tr.v. trans·mog·ri·fied, trans·mog·ri·fy·ing, trans·mog·ri·fies To change into a different shape or form, especially one that is fantastic or bizarre.

markseel

Thanks Transmorgrifox - that's a lot of really good info  :icon_biggrin:

ElectricDruid

Quote from: Transmogrifox on August 29, 2016, 01:49:46 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/

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


Transmogrifox

Quote from: ElectricDruid on September 06, 2016, 06:46:41 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:
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:
trans·mog·ri·fy
tr.v. trans·mog·ri·fied, trans·mog·ri·fy·ing, trans·mog·ri·fies To change into a different shape or form, especially one that is fantastic or bizarre.

ElectricDruid

Quote from: Transmogrifox on September 07, 2016, 01:31:31 PM
If the BBD LFO shape is desired, the computational "hammer" is to simply compute every cycle as you and Brian Neunaber pointed out:
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

mhelin

#52
Quote from: 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.

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.

markseel

#53
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).



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.

mhelin

#54
Quote from: markseel on September 28, 2016, 10:49:51 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.

matze44

Hi Mark,

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

Greetings,

Matthias

markseel

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.

markseel

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):


I'll post the analog board that stacks on this digital board soon.

Digital Larry

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...
Digital Larry
Want to quickly design your own effects patches for the Spin FV-1 DSP chip?
https://github.com/HolyCityAudio/SpinCAD-Designer

loopmasta

#59
Hi Mark. Great project. Do you sell this board as a kit? By the way the github link above is not working.