Doc updates

This commit is contained in:
Ross Owen
2012-08-30 14:21:17 +01:00
parent e449050b40
commit 99cdee6e2b
45 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,167 @@
//#include "devicedefines.h"
#define MAX_MIX_COUNT 8
#define MIX_INPUTS 18
#define DOMIX_TOP(i) \
.cc_top doMix##i.function,doMix##i; \
.align 4 ;\
.globl doMix##i ;\
.globl doMix##i##.nstackwords ;\
.globl doMix##i##.maxthreads ; \
.globl doMix##i##.maxtimers ; \
.globl doMix##i##.maxchanends ; \
.globl doMix##i##.maxsync ;\
.linkset doMix##i##.locnoside, 1; \
.linkset doMix##i##.locnochandec, 1;\
.linkset doMix##i##.nstackwords, 0 ;\
.linkset doMix##i##.maxchanends, 0 ;\
.linkset doMix##i##.maxtimers, 0 ;\
.linkset doMix##i##.maxthreads, 1; \
doMix##i##: ;\
set cp, r0; \
set dp, r1; \
lsub r0, r1, r0, r0, r0;\
.label_##i##:
#define DOMIX_BOT(i) \
ldap r11, _dp; \
set dp, r11;\
ldap r11, _cp;\
set cp, r11;\
\
mov r0, r1;\
ldc r2, 0x19;\
sext r0, r2;\
eq r0, r0, r1;\
bf r0, .L20; \
\
shl r0, r1, 0x7;\
retsp 0x0;\
\
\
.cc_bottom doMix##i##.function;
#define N MIX_INPUTS
#define BODY(i) \
ldw r2,cp[i]; \
ldw r11, dp[i]; \
maccs r1, r0, r2, r11;
.text
.L20:\
lss r0, r1, r3;\
bt r0, .L16; \
ldw r0, cp[.LC0];\
retsp 0x0; \
.L16:\
ldw r0, cp[.LC1];\
retsp 0x0; \
#if(MAX_MIX_COUNT > 0)
DOMIX_TOP(0)
#include "repeat.h"
DOMIX_BOT(0)
#endif
#if(MAX_MIX_COUNT > 1)
DOMIX_TOP(1)
#include "repeat.h"
DOMIX_BOT(1)
#endif
#if(MAX_MIX_COUNT > 2)
DOMIX_TOP(2)
#include "repeat.h"
DOMIX_BOT(2)
#endif
#if(MAX_MIX_COUNT > 3)
DOMIX_TOP(3)
#include "repeat.h"
DOMIX_BOT(3)
#endif
#if(MAX_MIX_COUNT > 4)
DOMIX_TOP(4)
#include "repeat.h"
DOMIX_BOT(4)
#endif
#if(MAX_MIX_COUNT > 5)
DOMIX_TOP(5)
#include "repeat.h"
DOMIX_BOT(5)
#endif
#if(MAX_MIX_COUNT > 6)
DOMIX_TOP(6)
#include "repeat.h"
DOMIX_BOT(6)
#endif
#if(MAX_MIX_COUNT > 7)
DOMIX_TOP(7)
#include "repeat.h"
DOMIX_BOT(7)
#endif
#if(MAX_MIX_COUNT>8)
#error MAX_MIX_COUNT>7
#endif
/* We need MIX_OUTPUT x setPtr functions */
#undef N
#undef BODY
#define N MAX_MIX_COUNT
.cc_top setPtr.function,setPtr;
.align 4 ;
.globl setPtr.nstackwords;
.globl setPtr;
.globl setPtr.maxthreads;
.globl setPtr.maxtimers;
.globl setPtr.maxchanends;
.globl setPtr.maxsync;
.linkset setPtr.locnoside, 1;
.linkset setPtr.locnochandec, 1;
.linkset setPtr.nstackwords, 0;
.linkset setPtr.maxchanends, 0;
.linkset setPtr.maxtimers, 0;
.linkset setPtr.maxthreads, 1;
setPtr:
shl r2, r2, 1
.xtabranch .label_0
bru r2
#define BODY(i) \
ldap r11, .label_##i; \
bu setPtr_go
#include "repeat.h"
setPtr_go:
shl r0, r0, 3;
ldc r2, 0x80;
add r1, r1, r2;
st8 r1, r11[r0];
retsp 0;
.cc_bottom setPtr.function
.section .cp.const4, "acM", @progbits, 4
.LC0:
.align 4
.int 0x7fffff00
.LC1:
.int 0x80000000
#undef N
#undef BODY

View File

@@ -0,0 +1,32 @@
#ifndef __mixer_h__
#define __mixer_h__
enum mix_ctl_cmd {
SET_SAMPLES_TO_HOST_MAP,
SET_SAMPLES_TO_DEVICE_MAP,
SET_MIX_MULT,
SET_MIX_MAP,
SET_MIX_IN_VOL,
SET_MIX_OUT_VOL,
GET_INPUT_LEVELS,
GET_STREAM_LEVELS,
GET_OUTPUT_LEVELS
};
/** Digital sample mixer.
*
* This thread mixes audio streams between the decouple() thread and
* the audio() thread.
*
* \param c_to_host a chanend connected to the decouple() thread for
* receiving/transmitting samples
* \param c_to_audio a chanend connected to the audio() thread for
* receiving/transmitting samples
* \param c_mix_ctl a chanend connected to the Endpoint0() thread for
* receiving control commands
*
*/
void mixer(chanend c_to_host, chanend c_to_audio, chanend c_mix_ctl);
#endif

View File

@@ -0,0 +1,704 @@
#include <xs1.h>
#include <print.h>
#include "mixer.h"
#include "devicedefines.h"
#include "xc_ptr.h"
#ifdef MIXER
#define FAST_MIXER 1
#warning USING FAST MIXER
#ifdef OUT_VOLUME_IN_MIXER
static unsigned int multOut_array[NUM_USB_CHAN_OUT + 1];
static xc_ptr multOut;
#endif
#ifdef IN_VOLUME_IN_MIXER
unsigned int multIn_array[NUM_USB_CHAN_IN + 1];
static xc_ptr multIn;
#endif
#if defined (LEVEL_METER_LEDS) || defined (LEVEL_METER_HOST)
static unsigned abs(int x)
{
#if 0
if (x < 0)
return x*-1;
return x;
#else
int const mask = x >> sizeof(int) * 8 - 1;
return (x + mask) ^ mask;
#endif
}
#endif
int samples_array[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT + 1]; /* One larger for an "off" channel for mixer sources" */
xc_ptr samples;
int savedsamples2[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT];
int samples_to_host_map_array[NUM_USB_CHAN_IN];
xc_ptr samples_to_host_map;
int samples_to_device_map_array[NUM_USB_CHAN_OUT];
xc_ptr samples_to_device_map;
#if MAX_MIX_COUNT > 0
int mix_mult_array[MAX_MIX_COUNT][MIX_INPUTS];
xc_ptr mix_mult;
#define write_word_to_mix_mult(x,y,val) write_via_xc_ptr_indexed(mix_mult,((x)*MIX_INPUTS)+(y), val)
#define mix_mult_slice(x) (mix_mult + x * MIX_INPUTS * sizeof(int))
#ifndef FAST_MIXER
int mix_map_array[MAX_MIX_COUNT][MIX_INPUTS];
xc_ptr mix_map;
#define write_word_to_mix_map(x,y,val) write_via_xc_ptr_indexed(mix_map,((x)*MIX_INPUTS)+(y), val)
#define mix_map_slice(x) (mix_map + x * MIX_INPUTS * sizeof(int))
#endif
#endif
/* Arrays for level data */
int samples_to_host_inputs[NUM_USB_CHAN_IN]; /* Audio transmitted to host i.e. dev inputs */
#ifdef LEVEL_METER_LEDS
int samples_to_host_inputs_buff[NUM_USB_CHAN_IN]; /* Audio transmitted to host i.e. dev inputs */
#endif
static int samples_to_host_streams[NUM_USB_CHAN_OUT]; /* Audio stream to host from host */
static int samples_to_host_outputs[NUM_USB_CHAN_OUT]; /* Device outputs */
#if 0
#pragma xta command "add exclusion mixer1_rate_change"
#pragma xta command "analyse path mixer1_req mixer1_req"
#pragma xta command "set required - 10400 ns" /* 96kHz */
#endif
#if 0
#pragma xta command "add exclusion mixer2_rate_change"
#pragma xta command "analyse path mixer2_req mixer2_req"
#pragma xta command "set required - 10400 ns" /* 96kHz */
#endif
#if defined (LEVEL_METER_LEDS) || defined (LEVEL_METER_HOST)
static inline void ComputeMixerLevel(int sample, int i)
{
int x;
int y;
xc_ptr ptr;
x = abs(sample);
/* y = samples_to_host_outputs[i] */
asm("ldaw %0, dp[samples_to_host_outputs]":"=r"(ptr):); /* Might want to hoist this */
asm("ldw %0, %1[%2]":"=r"(y):"r"(ptr),"r"(i));
if(x > y)
{
/* samples_to_host_outputs[i] = x; */
write_via_xc_ptr_indexed(ptr,i,y);
//asm("stw %0, %1[%2]"::"r"(y),"r"(ptr),"r"(i));
}
}
#endif
#ifdef FAST_MIXER
void setPtr(int src, int dst, int mix);
int doMix0(xc_ptr samples, xc_ptr mult);
int doMix1(xc_ptr samples, xc_ptr mult);
int doMix2(xc_ptr samples, xc_ptr mult);
int doMix3(xc_ptr samples, xc_ptr mult);
int doMix4(xc_ptr samples, xc_ptr mult);
int doMix5(xc_ptr samples, xc_ptr mult);
int doMix6(xc_ptr samples, xc_ptr mult);
int doMix7(xc_ptr samples, xc_ptr mult);
int doMix8(xc_ptr samples, xc_ptr mult);
#else
/* DO NOT inline, causes 10.4.2 tools to add extra loads in loop */
/* At 18 x 12dB we could get 64 x bigger */
#pragma unsafe arrays
int doMix(xc_ptr samples, xc_ptr ptr, xc_ptr mult)
{
int h=0;
int l=0;
/* By breaking up the loop we keep things in the encoding for ldw (0-11) */
#pragma loop unroll
for (int i=0; i<MIX_INPUTS; i++)
{
int sample;
int index;
int m;
read_via_xc_ptr_indexed(index, ptr, i);
read_via_xc_ptr_indexed(sample,samples,index);
read_via_xc_ptr_indexed(m, mult, i);
{h,l} = macs(sample, m, h, l);
}
#if 1
/* Perform saturation */
l = sext(h, 25);
if(l != h)
{
//if(h < 0)
if(h>>32)
h = (0x80000000>>7);
else
h = (0x7fffff00>>7);
}
#endif
return h<<7;
}
#endif
#pragma unsafe arrays
void giveSamplesToHost(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multIn)
{
#if defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
int mult;
int h;
unsigned l;
#endif
#pragma loop unroll
for (int i=0;i<NUM_USB_CHAN_IN;i++)
{
int sample;
int index;
read_via_xc_ptr_indexed(index,ptr,i);
read_via_xc_ptr_indexed(sample,samples,index);
#if defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
#warning IN Vols in mixer, AFTER mix & map
//asm("ldw %0, %1[%2]":"=r"(mult):"r"(multIn),"r"(i));
read_via_xc_ptr_indexed(mult, multIn, i);
{h, l} = macs(mult, sample, 0, 0);
//h <<= 3 done on other side */
outuint(c, h);
#else
outuint(c,sample);
#endif
}
}
#pragma unsafe arrays
static void getSamplesFromHost(chanend c, xc_ptr samples, int base)
{
#pragma loop unroll
for (int i=0;i<NUM_USB_CHAN_OUT;i++)
{
int sample, x;
#if defined(OUT_VOLUME_IN_MIXER) && !defined(OUT_VOLUME_AFTER_MIX)
int mult;
int h;
unsigned l;
#endif
/* Receive sample from decouple */
sample = inuint(c);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
/* Compute peak level data */
x = abs(sample);
if(x > samples_to_host_streams[i])
samples_to_host_streams[i] = x;
#endif
#if defined(OUT_VOLUME_IN_MIXER) && !defined(OUT_VOLUME_AFTER_MIX)
#warning OUT Vols in mixer, BEFORE mix & map
read_via_xc_ptr_indexed(mult, multOut, i);
{h, l} = macs(mult, sample, 0, 0);
h<<=3;
write_via_xc_ptr_indexed(multOut, index, val);
write_via_xc_ptr_indexed(samples,base+i,h);
#else
write_via_xc_ptr_indexed(samples,base+i,sample);
#endif
}
}
#pragma unsafe arrays
void giveSamplesToDevice(chanend c, xc_ptr samples, xc_ptr ptr, xc_ptr multOut)
{
#pragma loop unroll
for (int i=0;i<NUM_USB_CHAN_OUT;i++)
{
int sample,x;
#if defined(OUT_VOLUME_IN_MIXER) && defined(OUT_VOLUME_AFTER_MIX)
int mult;
int h;
unsigned l;
#endif
int index;
read_via_xc_ptr_indexed(index, ptr, i);
read_via_xc_ptr_indexed(sample, samples, index)
#if defined(OUT_VOLUME_IN_MIXER) && defined(OUT_VOLUME_AFTER_MIX)
#warning OUT Vols in mixer, AFTER mix & map
read_via_xc_ptr_indexed(mult, multOut, i);
{h, l} = macs(mult, sample, 0, 0);
//h <<= 3 done in audio thread
outuint(c, h);
#else
outuint(c, sample);
#endif
}
}
#pragma unsafe arrays
void getSamplesFromDevice(chanend c, xc_ptr samples, int base)
{
#if defined(IN_VOLUME_IN_MIXER) && !defined(IN_VOLUME_AFTER_MIX)
int mult;
int h;
unsigned l;
#endif
#pragma loop unroll
for (int i=0;i<NUM_USB_CHAN_IN;i++)
{
int sample;
int x;
sample = inuint(c);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
/* Compute peak level data */
x = abs(sample);
if(x > samples_to_host_inputs[i])
samples_to_host_inputs[i] = x;
#endif
#if defined(IN_VOLUME_IN_MIXER) && !defined(IN_VOLUME_AFTER_MIX)
read_via_xc_ptr_indexed(mult, multIn, i);
{h, l} = macs(mult, sample, 0, 0);
h <<=3;
write_via_xc_ptr_indexed(samples,base+i,h);
#else
write_via_xc_ptr_indexed(samples,base+i,sample);
#endif
}
}
int mixer1_mix2_flag = (DEFAULT_FREQ > 96000);
#pragma unsafe arrays
void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
{
int mixed;
unsigned cmd;
while (1)
{
#pragma xta endpoint "mixer1_req"
inuint(c_mixer2);
/* Request data from decouple thread */
outuint(c_host, 0);
/* Between request to decouple and respose ~ 400nS latency for interrupt to fire */
select
{
case inuint_byref(c_mix_ctl, cmd):
{
int mix, index, val;
switch (cmd)
{
#if MAX_MIX_COUNT > 0
case SET_SAMPLES_TO_HOST_MAP:
index = inuint(c_mix_ctl);
val = inuint(c_mix_ctl);
inct(c_mix_ctl);
write_via_xc_ptr_indexed(samples_to_host_map,
index,
val);
break;
case SET_SAMPLES_TO_DEVICE_MAP:
index = inuint(c_mix_ctl);
val = inuint(c_mix_ctl);
inct(c_mix_ctl);
write_via_xc_ptr_indexed(samples_to_device_map,index,val);
break;
case SET_MIX_MULT:
mix = inuint(c_mix_ctl);
index = inuint(c_mix_ctl);
val = inuint(c_mix_ctl);
inct(c_mix_ctl);
write_word_to_mix_mult(mix, index, val);
break;
case SET_MIX_MAP:
mix = inuint(c_mix_ctl);
index = inuint(c_mix_ctl); /* mixer input */
val = inuint(c_mix_ctl); /* source */
inct(c_mix_ctl);
#ifdef FAST_MIXER
setPtr(index, val, mix);
#else
write_word_to_mix_map(mix, index, val);
#endif
break;
#endif /* if MAX_MIX_COUNT > 0 */
#ifdef IN_VOLUME_IN_MIXER
case SET_MIX_IN_VOL:
index = inuint(c_mix_ctl);
val = inuint(c_mix_ctl);
inct(c_mix_ctl);
write_via_xc_ptr_indexed(multIn, index, val);
break;
#endif
#ifdef OUT_VOLUME_IN_MIXER
case SET_MIX_OUT_VOL:
index = inuint(c_mix_ctl);
val = inuint(c_mix_ctl);
inct(c_mix_ctl);
write_via_xc_ptr_indexed(multOut, index, val);
break;
#endif
case GET_STREAM_LEVELS:
index = inuint(c_mix_ctl);
chkct(c_mix_ctl, XS1_CT_END);
outuint(c_mix_ctl, samples_to_host_streams[index]);
outct(c_mix_ctl, XS1_CT_END);
samples_to_host_streams[index] = 0;
break;
case GET_INPUT_LEVELS:
index = inuint(c_mix_ctl);
chkct(c_mix_ctl, XS1_CT_END);
#ifdef LEVEL_METER_LEDS
/* Level LEDS process reseting samples_to_host_inputs
* Other side makes sure we don't miss a peak */
read_via_xc_ptr_indexed(val, samples_to_host_inputs_buff, index);
write_via_xc_ptr_indexed(samples_to_host_inputs_buff, index, 0);
#else
/* We dont have a level LEDs process, so reset ourselves */
read_via_xc_ptr_indexed(val, samples_to_host_inputs, index);
write_via_xc_ptr_indexed(samples_to_host_inputs, index, 0);
#endif
outuint(c_mix_ctl, val);
outct(c_mix_ctl, XS1_CT_END);
break;
#if MAX_MIX_COUNT > 0
case GET_OUTPUT_LEVELS:
index = inuint(c_mix_ctl);
chkct(c_mix_ctl, XS1_CT_END);
read_via_xc_ptr_indexed(val, samples_to_host_outputs, index);
write_via_xc_ptr_indexed(samples_to_host_outputs, index, mix);
outuint(c_mix_ctl, val);
outct(c_mix_ctl, XS1_CT_END);
break;
#endif
}
break;
}
default:
/* Select default */
break;
}
/* Get response from decouple */
if(testct(c_host))
{
int sampFreq;
#pragma xta endpoint "mixer1_rate_change"
inct(c_host);
sampFreq = inuint(c_host);
mixer1_mix2_flag = sampFreq > 96000;
#pragma loop unroll
for (int i=0;i<MAX_MIX_COUNT;i++)
{
write_via_xc_ptr_indexed(samples,
(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i),
0);
}
/* Inform mixer 2 about freq change */
outct(c_mixer2, XS1_CT_END);
outuint(c_mixer2, sampFreq);
/* Wait for handshake and pass on */
chkct(c_mixer2, XS1_CT_END);
outct(c_host, XS1_CT_END);
}
else
{
inuint(c_host);
#if MAX_MIX_COUNT > 0
outuint(c_mixer2, 0);
giveSamplesToHost(c_host, samples, samples_to_host_map, multIn);
outuint(c_mixer2, 0);
inuint(c_mixer2);
getSamplesFromHost(c_host, samples, 0);
outuint(c_mixer2, 0);
inuint(c_mixer2);
#ifdef FAST_MIXER
mixed = doMix0(samples, mix_mult_slice(0));
#else
mixed = doMix(samples,mix_map_slice(0),mix_mult_slice(0));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 0), mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 0);
#endif
#if (MAX_FREQ > 96000)
if (!mixer1_mix2_flag)
#endif
{
#if MAX_MIX_COUNT > 2
#ifdef FAST_MIXER
mixed = doMix2(samples, mix_mult_slice(2));
#else
mixed = doMix(samples,mix_map_slice(2),mix_mult_slice(2));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 2), mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 2);
#endif
#endif
#if MAX_MIX_COUNT > 4
#ifdef FAST_MIXER
mixed = doMix4(samples, mix_mult_slice(4));
#else
mixed = doMix(samples,mix_map_slice(4),mix_mult_slice(4));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 4), mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 4);
#endif
#endif
#if MAX_MIX_COUNT > 6
#ifdef FAST_MIXER
mixed = doMix6(samples, mix_mult_slice(6));
#else
mixed = doMix(samples,mix_map_slice(6),mix_mult_slice(6));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 6), mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 6);
#endif
#endif
}
#else /* IF MAX_MIX_COUNT > 0 */
/* No mixes, this thread runs on its own doing just volume */
giveSamplesToDevice(c_mixer2, samples, samples_to_device_map, multOut);
getSamplesFromDevice(c_mixer2, samples, NUM_USB_CHAN_OUT);
giveSamplesToHost(c_host, samples, samples_to_host_map, multIn);
getSamplesFromHost(c_host, samples, 0);
#endif
}
}
}
int mixer2_mix2_flag = (DEFAULT_FREQ > 96000);
#pragma unsafe arrays
void mixer2(chanend c_mixer1, chanend c_audio)
{
int mixed;
while (1) {
outuint(c_mixer1, 0);
#pragma xta endpoint "mixer2_req"
inuint(c_audio);
if(testct(c_mixer1))
{
int sampFreq;
#pragma xta endpoint "mixer2_rate_change"
inct(c_mixer1);
sampFreq = inuint(c_mixer1);
mixer2_mix2_flag = sampFreq > 96000;
for (int i=0;i<MAX_MIX_COUNT;i++)
{
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i), 0);
}
/* Inform audio thread about freq change */
outct(c_audio, XS1_CT_END);
outuint(c_audio, sampFreq);
/* Wait for handshake and pass on */
chkct(c_audio, XS1_CT_END);
outct(c_mixer1, XS1_CT_END);
}
else {
(void) inuint(c_mixer1);
giveSamplesToDevice(c_audio, samples, samples_to_device_map, multOut);
inuint(c_mixer1);
outuint(c_mixer1, 0);
getSamplesFromDevice(c_audio, samples, NUM_USB_CHAN_OUT);
inuint(c_mixer1);
outuint(c_mixer1, 0);
#if MAX_MIX_COUNT > 1
#ifdef FAST_MIXER
mixed = doMix1(samples, mix_mult_slice(1));
#else
mixed = doMix(samples,mix_map_slice(1),mix_mult_slice(1));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 1), mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 1);
#endif
#endif
#if (MAX_FREQ > 96000)
if (!mixer2_mix2_flag)
#endif
{
#if MAX_MIX_COUNT > 3
#ifdef FAST_MIXER
mixed = doMix3(samples, mix_mult_slice(3));
#else
mixed = doMix(samples,mix_map_slice(3),mix_mult_slice(3));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 3), mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 3);
#endif
#endif
#if MAX_MIX_COUNT > 5
#ifdef FAST_MIXER
mixed = doMix5(samples, mix_mult_slice(5));
#else
mixed = doMix(samples,mix_map_slice(5),mix_mult_slice(5));
#endif
write_via_xc_ptr_indexed(samples, NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 5, mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 5);
#endif
#endif
#if MAX_MIX_COUNT > 7
#ifdef FAST_MIXER
mixed = doMix7(samples, mix_mult_slice(7));
#else
mixed = doMix(samples,mix_map_slice(7),mix_mult_slice(7));
#endif
write_via_xc_ptr_indexed(samples, NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 7, mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 7);
#endif
#endif
}
}
}
}
void mixer(chanend c_mix_in, chanend c_mix_out, chanend c_mix_ctl)
{
chan c;
multOut = array_to_xc_ptr((multOut_array,unsigned[]));
multIn = array_to_xc_ptr((multIn_array,unsigned[]));
samples = array_to_xc_ptr((samples_array,unsigned[]));
samples_to_host_map =
array_to_xc_ptr((samples_to_host_map_array,unsigned[]));
samples_to_device_map =
array_to_xc_ptr((samples_to_device_map_array,unsigned[]));
#if MAX_MIX_COUNT >0
mix_mult = array_to_xc_ptr((mix_mult_array,unsigned[]));
#ifndef FAST_MIXER
mix_map = array_to_xc_ptr((mix_map_array,unsigned[]));
#endif
#endif
for (int i=0;i<NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT;i++)
{
write_via_xc_ptr_indexed(samples,i,0);
}
{
int num_mixes = DEFAULT_FREQ > 96000 ? 2 : MAX_MIX_COUNT;
for (int i=0;i<NUM_USB_CHAN_OUT;i++)
{
asm("stw %0, %1[%2]"::
"r"(i),
"r"(samples_to_device_map),
"r"(i));
}
}
#ifdef OUT_VOLUME_IN_MIXER
for (int i=0;i<NUM_USB_CHAN_OUT;i++)
{
write_via_xc_ptr_indexed(multOut, i, MAX_VOL);
}
#endif
#ifdef IN_VOLUME_IN_MIXER
for (int i=0;i<NUM_USB_CHAN_IN;i++)
{
write_via_xc_ptr_indexed(multIn, i, MAX_VOL);
}
#endif
for (int i=0;i<NUM_USB_CHAN_IN;i++)
{
write_via_xc_ptr_indexed(samples_to_host_map, i, NUM_USB_CHAN_OUT + i);
}
#if MAX_MIX_COUNT> 0
for (int i=0;i<MAX_MIX_COUNT;i++)
for (int j=0;j<MIX_INPUTS;j++)
{
#ifndef FAST_MIXER
write_word_to_mix_map(i,j, j < 16 ? j : j + 2);
#endif
write_word_to_mix_mult(i,j, i==j ? MAX_VOL >> 3 : 0);
}
#endif
par
{
#if (MAX_MIX_COUNT > 0)
mixer1(c_mix_in, c_mix_ctl, c);
mixer2(c, c_mix_out);
#else
mixer1(c_mix_in, c_mix_ctl, c_mix_out);
#endif
}
}
#endif

View File

@@ -0,0 +1,777 @@
#ifndef N
#error "N must be defined before including repeat.h"
#endif
#if N > 256
#error "N cannot be larger than 256"
#endif
#ifndef BODY
#error "BODY must be defined before including repeat.h"
#endif
#if N > 0
BODY(0)
#endif
#if N > 1
BODY(1)
#endif
#if N > 2
BODY(2)
#endif
#if N > 3
BODY(3)
#endif
#if N > 4
BODY(4)
#endif
#if N > 5
BODY(5)
#endif
#if N > 6
BODY(6)
#endif
#if N > 7
BODY(7)
#endif
#if N > 8
BODY(8)
#endif
#if N > 9
BODY(9)
#endif
#if N > 10
BODY(10)
#endif
#if N > 11
BODY(11)
#endif
#if N > 12
BODY(12)
#endif
#if N > 13
BODY(13)
#endif
#if N > 14
BODY(14)
#endif
#if N > 15
BODY(15)
#endif
#if N > 16
BODY(16)
#endif
#if N > 17
BODY(17)
#endif
#if N > 18
BODY(18)
#endif
#if N > 19
BODY(19)
#endif
#if N > 20
BODY(20)
#endif
#if N > 21
BODY(21)
#endif
#if N > 22
BODY(22)
#endif
#if N > 23
BODY(23)
#endif
#if N > 24
BODY(24)
#endif
#if N > 25
BODY(25)
#endif
#if N > 26
BODY(26)
#endif
#if N > 27
BODY(27)
#endif
#if N > 28
BODY(28)
#endif
#if N > 29
BODY(29)
#endif
#if N > 30
BODY(30)
#endif
#if N > 31
BODY(31)
#endif
#if N > 32
BODY(32)
#endif
#if N > 33
BODY(33)
#endif
#if N > 34
BODY(34)
#endif
#if N > 35
BODY(35)
#endif
#if N > 36
BODY(36)
#endif
#if N > 37
BODY(37)
#endif
#if N > 38
BODY(38)
#endif
#if N > 39
BODY(39)
#endif
#if N > 40
BODY(40)
#endif
#if N > 41
BODY(41)
#endif
#if N > 42
BODY(42)
#endif
#if N > 43
BODY(43)
#endif
#if N > 44
BODY(44)
#endif
#if N > 45
BODY(45)
#endif
#if N > 46
BODY(46)
#endif
#if N > 47
BODY(47)
#endif
#if N > 48
BODY(48)
#endif
#if N > 49
BODY(49)
#endif
#if N > 50
BODY(50)
#endif
#if N > 51
BODY(51)
#endif
#if N > 52
BODY(52)
#endif
#if N > 53
BODY(53)
#endif
#if N > 54
BODY(54)
#endif
#if N > 55
BODY(55)
#endif
#if N > 56
BODY(56)
#endif
#if N > 57
BODY(57)
#endif
#if N > 58
BODY(58)
#endif
#if N > 59
BODY(59)
#endif
#if N > 60
BODY(60)
#endif
#if N > 61
BODY(61)
#endif
#if N > 62
BODY(62)
#endif
#if N > 63
BODY(63)
#endif
#if N > 64
BODY(64)
#endif
#if N > 65
BODY(65)
#endif
#if N > 66
BODY(66)
#endif
#if N > 67
BODY(67)
#endif
#if N > 68
BODY(68)
#endif
#if N > 69
BODY(69)
#endif
#if N > 70
BODY(70)
#endif
#if N > 71
BODY(71)
#endif
#if N > 72
BODY(72)
#endif
#if N > 73
BODY(73)
#endif
#if N > 74
BODY(74)
#endif
#if N > 75
BODY(75)
#endif
#if N > 76
BODY(76)
#endif
#if N > 77
BODY(77)
#endif
#if N > 78
BODY(78)
#endif
#if N > 79
BODY(79)
#endif
#if N > 80
BODY(80)
#endif
#if N > 81
BODY(81)
#endif
#if N > 82
BODY(82)
#endif
#if N > 83
BODY(83)
#endif
#if N > 84
BODY(84)
#endif
#if N > 85
BODY(85)
#endif
#if N > 86
BODY(86)
#endif
#if N > 87
BODY(87)
#endif
#if N > 88
BODY(88)
#endif
#if N > 89
BODY(89)
#endif
#if N > 90
BODY(90)
#endif
#if N > 91
BODY(91)
#endif
#if N > 92
BODY(92)
#endif
#if N > 93
BODY(93)
#endif
#if N > 94
BODY(94)
#endif
#if N > 95
BODY(95)
#endif
#if N > 96
BODY(96)
#endif
#if N > 97
BODY(97)
#endif
#if N > 98
BODY(98)
#endif
#if N > 99
BODY(99)
#endif
#if N > 100
BODY(100)
#endif
#if N > 101
BODY(101)
#endif
#if N > 102
BODY(102)
#endif
#if N > 103
BODY(103)
#endif
#if N > 104
BODY(104)
#endif
#if N > 105
BODY(105)
#endif
#if N > 106
BODY(106)
#endif
#if N > 107
BODY(107)
#endif
#if N > 108
BODY(108)
#endif
#if N > 109
BODY(109)
#endif
#if N > 110
BODY(110)
#endif
#if N > 111
BODY(111)
#endif
#if N > 112
BODY(112)
#endif
#if N > 113
BODY(113)
#endif
#if N > 114
BODY(114)
#endif
#if N > 115
BODY(115)
#endif
#if N > 116
BODY(116)
#endif
#if N > 117
BODY(117)
#endif
#if N > 118
BODY(118)
#endif
#if N > 119
BODY(119)
#endif
#if N > 120
BODY(120)
#endif
#if N > 121
BODY(121)
#endif
#if N > 122
BODY(122)
#endif
#if N > 123
BODY(123)
#endif
#if N > 124
BODY(124)
#endif
#if N > 125
BODY(125)
#endif
#if N > 126
BODY(126)
#endif
#if N > 127
BODY(127)
#endif
#if N > 128
BODY(128)
#endif
#if N > 129
BODY(129)
#endif
#if N > 130
BODY(130)
#endif
#if N > 131
BODY(131)
#endif
#if N > 132
BODY(132)
#endif
#if N > 133
BODY(133)
#endif
#if N > 134
BODY(134)
#endif
#if N > 135
BODY(135)
#endif
#if N > 136
BODY(136)
#endif
#if N > 137
BODY(137)
#endif
#if N > 138
BODY(138)
#endif
#if N > 139
BODY(139)
#endif
#if N > 140
BODY(140)
#endif
#if N > 141
BODY(141)
#endif
#if N > 142
BODY(142)
#endif
#if N > 143
BODY(143)
#endif
#if N > 144
BODY(144)
#endif
#if N > 145
BODY(145)
#endif
#if N > 146
BODY(146)
#endif
#if N > 147
BODY(147)
#endif
#if N > 148
BODY(148)
#endif
#if N > 149
BODY(149)
#endif
#if N > 150
BODY(150)
#endif
#if N > 151
BODY(151)
#endif
#if N > 152
BODY(152)
#endif
#if N > 153
BODY(153)
#endif
#if N > 154
BODY(154)
#endif
#if N > 155
BODY(155)
#endif
#if N > 156
BODY(156)
#endif
#if N > 157
BODY(157)
#endif
#if N > 158
BODY(158)
#endif
#if N > 159
BODY(159)
#endif
#if N > 160
BODY(160)
#endif
#if N > 161
BODY(161)
#endif
#if N > 162
BODY(162)
#endif
#if N > 163
BODY(163)
#endif
#if N > 164
BODY(164)
#endif
#if N > 165
BODY(165)
#endif
#if N > 166
BODY(166)
#endif
#if N > 167
BODY(167)
#endif
#if N > 168
BODY(168)
#endif
#if N > 169
BODY(169)
#endif
#if N > 170
BODY(170)
#endif
#if N > 171
BODY(171)
#endif
#if N > 172
BODY(172)
#endif
#if N > 173
BODY(173)
#endif
#if N > 174
BODY(174)
#endif
#if N > 175
BODY(175)
#endif
#if N > 176
BODY(176)
#endif
#if N > 177
BODY(177)
#endif
#if N > 178
BODY(178)
#endif
#if N > 179
BODY(179)
#endif
#if N > 180
BODY(180)
#endif
#if N > 181
BODY(181)
#endif
#if N > 182
BODY(182)
#endif
#if N > 183
BODY(183)
#endif
#if N > 184
BODY(184)
#endif
#if N > 185
BODY(185)
#endif
#if N > 186
BODY(186)
#endif
#if N > 187
BODY(187)
#endif
#if N > 188
BODY(188)
#endif
#if N > 189
BODY(189)
#endif
#if N > 190
BODY(190)
#endif
#if N > 191
BODY(191)
#endif
#if N > 192
BODY(192)
#endif
#if N > 193
BODY(193)
#endif
#if N > 194
BODY(194)
#endif
#if N > 195
BODY(195)
#endif
#if N > 196
BODY(196)
#endif
#if N > 197
BODY(197)
#endif
#if N > 198
BODY(198)
#endif
#if N > 199
BODY(199)
#endif
#if N > 200
BODY(200)
#endif
#if N > 201
BODY(201)
#endif
#if N > 202
BODY(202)
#endif
#if N > 203
BODY(203)
#endif
#if N > 204
BODY(204)
#endif
#if N > 205
BODY(205)
#endif
#if N > 206
BODY(206)
#endif
#if N > 207
BODY(207)
#endif
#if N > 208
BODY(208)
#endif
#if N > 209
BODY(209)
#endif
#if N > 210
BODY(210)
#endif
#if N > 211
BODY(211)
#endif
#if N > 212
BODY(212)
#endif
#if N > 213
BODY(213)
#endif
#if N > 214
BODY(214)
#endif
#if N > 215
BODY(215)
#endif
#if N > 216
BODY(216)
#endif
#if N > 217
BODY(217)
#endif
#if N > 218
BODY(218)
#endif
#if N > 219
BODY(219)
#endif
#if N > 220
BODY(220)
#endif
#if N > 221
BODY(221)
#endif
#if N > 222
BODY(222)
#endif
#if N > 223
BODY(223)
#endif
#if N > 224
BODY(224)
#endif
#if N > 225
BODY(225)
#endif
#if N > 226
BODY(226)
#endif
#if N > 227
BODY(227)
#endif
#if N > 228
BODY(228)
#endif
#if N > 229
BODY(229)
#endif
#if N > 230
BODY(230)
#endif
#if N > 231
BODY(231)
#endif
#if N > 232
BODY(232)
#endif
#if N > 233
BODY(233)
#endif
#if N > 234
BODY(234)
#endif
#if N > 235
BODY(235)
#endif
#if N > 236
BODY(236)
#endif
#if N > 237
BODY(237)
#endif
#if N > 238
BODY(238)
#endif
#if N > 239
BODY(239)
#endif
#if N > 240
BODY(240)
#endif
#if N > 241
BODY(241)
#endif
#if N > 242
BODY(242)
#endif
#if N > 243
BODY(243)
#endif
#if N > 244
BODY(244)
#endif
#if N > 245
BODY(245)
#endif
#if N > 246
BODY(246)
#endif
#if N > 247
BODY(247)
#endif
#if N > 248
BODY(248)
#endif
#if N > 249
BODY(249)
#endif
#if N > 250
BODY(250)
#endif
#if N > 251
BODY(251)
#endif
#if N > 252
BODY(252)
#endif
#if N > 253
BODY(253)
#endif
#if N > 254
BODY(254)
#endif
#if N > 255
BODY(255)
#endif