First commit

This commit is contained in:
Dave Lacey
2011-07-07 20:15:51 +01:00
commit 02b07ed9f3
70 changed files with 15434 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,669 @@
#include <xs1.h>
#include <print.h>
#include "mixer.h"
#include "devicedefines.h"
#ifdef MIXER
#define FAST_MIXER 1
#warning USING FAST MIXER
#ifdef OUT_VOLUME_IN_MIXER
static unsigned int multOut[NUM_USB_CHAN_OUT + 1];
#endif
#ifdef IN_VOLUME_IN_MIXER
unsigned int multIn[NUM_USB_CHAN_IN + 1];
#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[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT + 1]; /* One larger for an "off" channel for mixer sources" */
int savedsamples2[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT];
int samples_to_host_map[NUM_USB_CHAN_IN];
int samples_to_device_map[NUM_USB_CHAN_OUT];
#if MAX_MIX_COUNT > 0
int mix_mult[MAX_MIX_COUNT][MIX_INPUTS];
#ifndef FAST_MIXER
int mix_map[MAX_MIX_COUNT][MIX_INPUTS];
#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;
unsigned 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; */
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(const int samples[], int mult[]);
int doMix1(const int samples[], int mult[]);
int doMix2(const int samples[], int mult[]);
int doMix3(const int samples[], int mult[]);
int doMix4(const int samples[], int mult[]);
int doMix5(const int samples[], int mult[]);
int doMix6(const int samples[], int mult[]);
int doMix7(const int samples[], int mult[]);
int doMix8(const int samples[], int 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(const int samples[], const int ptr[], int 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++)
{
{h,l} = macs(samples[ptr[i]], mult[i], 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, const int samples[], const int ptr[], const unsigned 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;
sample = samples[ptr[i]];
#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));
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, const int 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
asm("ldw %0, %1[%2]":"=r"(mult):"r"(multOut),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
h<<=3;
asm("stw %0, %1[%2]"::"r"(h),"r"(samples),"r"(base+i));
#else
asm("stw %0, %1[%2]"::"r"(sample),"r"(samples),"r"(base+i));
#endif
}
}
#pragma unsafe arrays
void giveSamplesToDevice(chanend c, const int samples[],const int ptr[], const unsigned 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
sample = samples[ptr[i]];
#if defined(OUT_VOLUME_IN_MIXER) && defined(OUT_VOLUME_AFTER_MIX)
#warning OUT Vols in mixer, AFTER mix & map
mult = multOut[i];
//asm("ldw %0, %1[%2]":"=r"(mult):"r"(multOut),"r"(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, const int 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)
asm("ldw %0, %1[%2]":"=r"(mult):"r"(multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
h <<=3;
asm("stw %0, %1[%2]"::"r"(h),"r"(samples),"r"(base+i));
#else
asm("stw %0, %1[%2]"::"r"(sample),"r"(samples),"r"(base+i));
#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);
asm("stw %0, %1[%2]"::"r"(val),"r"(samples_to_host_map),"r"(index));
break;
case SET_SAMPLES_TO_DEVICE_MAP:
index = inuint(c_mix_ctl);
val = inuint(c_mix_ctl);
inct(c_mix_ctl);
asm("stw %0, %1[%2]"::"r"(val),"r"(samples_to_device_map),"r"(index));
break;
case SET_MIX_MULT:
mix = inuint(c_mix_ctl);
index = inuint(c_mix_ctl);
val = inuint(c_mix_ctl);
inct(c_mix_ctl);
asm("stw %0, %1[%2]"::"r"(val),"r"(mix_mult[mix]),"r"(index));
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
asm("stw %0, %1[%2]"::"r"(val),"r"(mix_map[mix]),"r"(index));
#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);
asm("stw %0, %1[%2]"::"r"(val),"r"(multIn),"r"(index));
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);
asm("stw %0, %1[%2]"::"r"(val),"r"(multOut),"r"(index));
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 */
asm("ldw %0, %1[%2]":"=r"(val):"r"(samples_to_host_inputs_buff),"r"(index));
asm("stw %0, %1[%2]"::"r"(0),"r"(samples_to_host_inputs_buff),"r"(index));
#else
/* We dont have a level LEDs process, so reset ourselves */
asm("ldw %0, %1[%2]":"=r"(val):"r"(samples_to_host_inputs),"r"(index));
asm("stw %0, %1[%2]"::"r"(0),"r"(samples_to_host_inputs),"r"(index));
#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);
asm("ldw %0, %1[%2]":"=r"(val):"r"(samples_to_host_outputs),"r"(index));
asm("stw %0, %1[%2]"::"r"(mix),"r"(samples_to_host_outputs),"r"(index));
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++)
{
asm("stw %0, %1[%2]"::"r"(0),"r"(samples),"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i));
}
/* 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[0]);
#else
mixed = doMix(samples,mix_map[0],mix_mult[0]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 0));
#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[2]);
#else
mixed = doMix(samples,mix_map[2],mix_mult[2]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 2));
#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[4]);
#else
mixed = doMix(samples,mix_map[4],mix_mult[4]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 4));
#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[6]);
#else
mixed = doMix(samples,mix_map[6],mix_mult[6]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 6));
#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++)
{
asm("stw %0, %1[%2]":: "r"(0),"r"(samples),"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + i));
}
/* 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[1]);
#else
mixed = doMix(samples,mix_map[1],mix_mult[1]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 1));
#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[3]);
#else
mixed = doMix(samples,mix_map[3],mix_mult[3]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 3));
#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[5]);
#else
mixed = doMix(samples,mix_map[5],mix_mult[5]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 5));
#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[7]);
#else
mixed = doMix(samples,mix_map[7],mix_mult[7]);
#endif
asm("stw %0, %1[%2]"::
"r"(mixed),"r"(samples),
"r"(NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 7));
#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;
for (int i=0;i<NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT;i++)
{
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++)
{
multOut[i] = MAX_VOL;
}
#endif
#ifdef IN_VOLUME_IN_MIXER
for (int i=0;i<NUM_USB_CHAN_IN;i++)
{
multIn[i] = MAX_VOL;
}
#endif
for (int i=0;i<NUM_USB_CHAN_IN;i++)
{
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
mix_map[i][j] = j < 16 ? j : j + 2;
#endif
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