Merge branch 'iosaudioaccessory' of git://git/apps/sc_usb_audio into iosaudioaccessory
This commit is contained in:
@@ -12,9 +12,7 @@
|
||||
* receiving/transmitting samples
|
||||
* \param c_config An optional channel that will be passed on to the
|
||||
* CODEC configuration functions.
|
||||
* \param c_i2c An optional channel that will be passed on to the
|
||||
* functions requiring i2c.
|
||||
*/
|
||||
void audio(chanend c_in, chanend ?c_dig, chanend ?c_config, chanend ?c_i2c);
|
||||
void audio(chanend c_in, chanend ?c_dig, chanend ?c_config);
|
||||
|
||||
#endif // __audio_h__
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <xs1.h>
|
||||
#include <xclib.h>
|
||||
#include <print.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "clocking.h"
|
||||
#include "audioports.h"
|
||||
@@ -64,8 +63,12 @@ extern void device_reboot(void);
|
||||
unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx)
|
||||
{
|
||||
unsigned sample;
|
||||
#if NUM_USB_CHAN_OUT > 0
|
||||
unsigned samplesOut[NUM_USB_CHAN_OUT];
|
||||
#endif
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
unsigned samplesIn[NUM_USB_CHAN_IN];
|
||||
#endif
|
||||
unsigned samplesInPrev[NUM_USB_CHAN_IN];
|
||||
unsigned tmp;
|
||||
unsigned index;
|
||||
@@ -73,15 +76,14 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
unsigned prev=0;
|
||||
int started = 0;
|
||||
#endif
|
||||
#ifndef CODEC_SLAVE
|
||||
int oldtime;
|
||||
#endif
|
||||
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
for (int i=0;i<NUM_USB_CHAN_IN;i++)
|
||||
{
|
||||
samplesIn[i] = 0;
|
||||
samplesInPrev[i] = 0;
|
||||
}
|
||||
#endif
|
||||
outuint(c_out, 0);
|
||||
|
||||
/* Check for sample freq change or new samples from mixer*/
|
||||
@@ -96,16 +98,21 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
#ifndef MIXER // Interfaces straight to decouple()
|
||||
(void) inuint(c_out);
|
||||
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
|
||||
{
|
||||
outuint(c_out, samplesIn[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NUM_USB_CHAN_OUT > 0
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
|
||||
{
|
||||
samplesOut[i] = inuint(c_out);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
|
||||
@@ -201,6 +208,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
tmp += 33;
|
||||
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_WIRES_DAC; i++)
|
||||
{
|
||||
p_i2s_dac[i] @ tmp <: 0;
|
||||
@@ -214,7 +222,6 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
{
|
||||
clearbuf(p_i2s_adc[i]);
|
||||
}
|
||||
oldtime = tmp-1+32;
|
||||
|
||||
/* TODO In master mode, the i/o loop assumes L/RCLK = 32bit clocks. We should check this every interation
|
||||
* and resync if we got a bclk glitch */
|
||||
@@ -237,17 +244,22 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
{
|
||||
#ifndef MIXER // Interfaces straight to decouple()
|
||||
(void) inuint(c_out);
|
||||
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
|
||||
{
|
||||
outuint(c_out, samplesIn[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NUM_USB_CHAN_OUT > 0
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
|
||||
{
|
||||
samplesOut[i] = inuint(c_out);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
|
||||
@@ -297,7 +309,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
|
||||
#pragma xta endpoint "i2s_output_l"
|
||||
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 0; i < I2S_CHANS_DAC; i+=2)
|
||||
{
|
||||
@@ -355,14 +367,16 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
for(int i = 1; i < I2S_CHANS_ADC; i += 2)
|
||||
{
|
||||
p_i2s_adc[index++] :> sample;
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
samplesIn[i] = bitrev(sample);
|
||||
|
||||
/* Store the previous left in left */
|
||||
samplesIn[i-1] = samplesInPrev[i];
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SPDIF
|
||||
#if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0)
|
||||
outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to SPDIF txt thread */
|
||||
sample = samplesOut[SPDIF_TX_INDEX + 1];
|
||||
outuint(c_spd_out, sample); /* Forward sample to SPDIF txt thread */
|
||||
@@ -385,7 +399,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
|
||||
tmp = 0;
|
||||
#pragma xta endpoint "i2s_output_r"
|
||||
#if (I2S_CHANS_DAC != 0)
|
||||
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
|
||||
#pragma loop unroll
|
||||
for(int i = 1; i < I2S_CHANS_DAC; i+=2)
|
||||
{
|
||||
@@ -440,7 +454,10 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
|
||||
for(int i = 1; i < I2S_CHANS_ADC; i += 2)
|
||||
{
|
||||
p_i2s_adc[index++] :> sample;
|
||||
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
samplesInPrev[i] = bitrev(sample);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -496,7 +513,7 @@ static unsigned dummy_deliver(chanend c_out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c_i2c)
|
||||
void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config)
|
||||
{
|
||||
#ifdef SPDIF
|
||||
chan c_spdif_out;
|
||||
@@ -511,10 +528,10 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c_i
|
||||
#endif
|
||||
|
||||
/* Initialise master clock generation */
|
||||
ClockingInit(c_i2c);
|
||||
ClockingInit();
|
||||
|
||||
/* Perform required CODEC/ADC/DAC initialisation */
|
||||
CodecInit(c_config, c_i2c);
|
||||
CodecInit(c_config);
|
||||
|
||||
while(1)
|
||||
{
|
||||
@@ -533,7 +550,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c_i
|
||||
divide = mClk / ( curSamFreq * 64 );
|
||||
|
||||
/* Configure clocking for required master clock */
|
||||
ClockingConfig(mClk, c_i2c);
|
||||
ClockingConfig(mClk);
|
||||
|
||||
if(!firstRun)
|
||||
{
|
||||
@@ -553,7 +570,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c_i
|
||||
firstRun = 0;
|
||||
|
||||
/* Configure CODEC/DAC/ADC for SampleFreq/MClk */
|
||||
CodecConfig(curSamFreq, mClk, c_config, c_i2c);
|
||||
CodecConfig(curSamFreq, mClk, c_config);
|
||||
|
||||
/* Configure audio ports */
|
||||
ConfigAudioPorts(divide);
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
/* Functions that handle master clock generation. These need modifying for an existing design */
|
||||
|
||||
/* Any initialisation required for master clock generation - run once at start up */
|
||||
void ClockingInit(chanend ?c);
|
||||
void ClockingInit(void);
|
||||
|
||||
/* Configuration for a specific master clock frequency - run every sample frequency change */
|
||||
void ClockingConfig(unsigned mClkFreq, chanend ?c);
|
||||
void ClockingConfig(unsigned mClkFreq);
|
||||
|
||||
|
||||
/** Clock generation and digital audio I/O handling.
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
/* TODO Are the channel args required? */
|
||||
|
||||
/* Any required CODEC initialisation - run once at start up */
|
||||
void CodecInit(chanend ?c_codec, chanend ?c_i2c);
|
||||
void CodecInit(chanend ?c_codec);
|
||||
|
||||
/* Configure condec for a specific mClk/Sample frquency - run on every sample frequency change */
|
||||
void CodecConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, chanend ?c_i2c);
|
||||
void CodecConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,27 @@
|
||||
|
||||
#include "customdefines.h"
|
||||
|
||||
/* Tidy up historical INPUT/OUTPUT defines. INPUT/OUTPUT now enabled based on channel count defines */
|
||||
#if !defined(NUM_USB_CHAN_IN)
|
||||
#error NUM_USB_CHAN_IN must be defined!
|
||||
#else
|
||||
#if (NUM_USB_CHAN_IN == 0)
|
||||
#undef INPUT
|
||||
#else
|
||||
#define INPUT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(NUM_USB_CHAN_OUT)
|
||||
#error NUM_USB_CHAN_OUT must be defined!
|
||||
#else
|
||||
#if (NUM_USB_CHAN_OUT == 0)
|
||||
#undef OUTPUT
|
||||
#else
|
||||
#define OUTPUT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(IO_EXPANSION) && (IO_EXPANSION == 0)
|
||||
#undef IO_EXPANSION
|
||||
#endif
|
||||
@@ -207,18 +228,18 @@
|
||||
#define ID_CLKSRC_EXT 42 /* Clock source ID (external) */
|
||||
#define ID_CLKSRC_ADAT 43 /* Clock source ID (external) */
|
||||
|
||||
#define ID_XU_MIXSEL 50
|
||||
#define ID_XU_OUT 51
|
||||
#define ID_XU_IN 52
|
||||
#define ID_XU_MIXSEL 50
|
||||
#define ID_XU_OUT 51
|
||||
#define ID_XU_IN 52
|
||||
|
||||
#define ID_MIXER_1 60
|
||||
#define ID_MIXER_1 60
|
||||
|
||||
#ifndef SERIAL_STR
|
||||
#define SERIAL_STR "0000" /* Serial number string */
|
||||
#define SERIAL_STR "0000" /* Serial number string */
|
||||
#endif
|
||||
|
||||
#define SERIAL_STR_INDEX 0x03
|
||||
#define MANUFACTURER_STR_INDEX 0x01
|
||||
#define SERIAL_STR_INDEX 0x03
|
||||
#define MANUFACTURER_STR_INDEX 0x01
|
||||
#define PRODUCT_STR_INDEX 0x02
|
||||
|
||||
/* Mixer defines */
|
||||
|
||||
@@ -40,8 +40,12 @@ extern unsigned char mixer1Crossbar[];
|
||||
extern short mixer1Weights[];
|
||||
|
||||
/* Device channel mapping */
|
||||
#if NUM_USB_CHAN_OUT > 0
|
||||
extern unsigned char channelMapAud[NUM_USB_CHAN_OUT];
|
||||
#endif
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
extern unsigned char channelMapUsb[NUM_USB_CHAN_IN];
|
||||
#endif
|
||||
|
||||
/* Mixer input mapping */
|
||||
extern unsigned char mixSel[MIX_INPUTS];
|
||||
@@ -52,10 +56,6 @@ extern unsigned int g_curSamFreq;
|
||||
extern unsigned int g_curSamFreq48000Family;
|
||||
extern unsigned int g_curSamFreqMultiplier;
|
||||
|
||||
/* Global level data */
|
||||
//unsigned short g_lvlMixOut[MAX_MIX_COUNT];
|
||||
//unsigned short g_lvlMixIn[NUM_USB_CHAN_IN + NUM_USB_CHAN_OUT];
|
||||
|
||||
/* Store an int into a char array: Note this allows non-word aligned access unlike reinerpret cast */
|
||||
void storeInt(unsigned char buffer[], int index, int val)
|
||||
{
|
||||
|
||||
@@ -170,12 +170,6 @@ unsigned char devQualDesc_Null[] =
|
||||
#define MIDI_LENGTH (0)
|
||||
#endif
|
||||
|
||||
#ifdef MIXER
|
||||
#define MIXER_LENGTH (13+1+18)
|
||||
#else
|
||||
#define MIXER_LENGTH (0)
|
||||
#endif
|
||||
|
||||
#ifdef IAP
|
||||
#define IAP_LENGTH (30)
|
||||
#else
|
||||
@@ -191,9 +185,18 @@ unsigned char devQualDesc_Null[] =
|
||||
#endif
|
||||
|
||||
#ifdef MIXER
|
||||
#define LEN_XU_MIX (17)
|
||||
#define LEN_XU_MIX (17)
|
||||
#define MIX_BMCONTROLS_LEN_TMP ((MAX_MIX_COUNT * MIX_INPUTS) / 8)
|
||||
|
||||
#if ((MAX_MIX_COUNT * MIX_INPUTS)%8)==0
|
||||
#define MIX_BMCONTROLS_LEN (MIX_BMCONTROLS_LEN_TMP)
|
||||
#else
|
||||
#define MIX_BMCONTROLS_LEN (MIX_BMCONTROLS_LEN_TMP+1)
|
||||
#endif
|
||||
#define MIXER_LENGTH (13+1+MIX_BMCONTROLS_LEN)
|
||||
#else
|
||||
#define LEN_XU_MIX (0)
|
||||
#define LEN_XU_MIX (0)
|
||||
#define MIXER_LENGTH (0)
|
||||
#endif
|
||||
|
||||
#define LEN_CLK (8)
|
||||
@@ -219,7 +222,7 @@ unsigned char devQualDesc_Null[] =
|
||||
|
||||
|
||||
/* Total length of config descriptor */
|
||||
#define CFG_TOTAL_LENGTH_A2 (7 + 26 + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 16) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH)
|
||||
#define CFG_TOTAL_LENGTH_A2 (7 + 26 + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 18) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH)
|
||||
|
||||
/* Define for number of audio interfaces (+1 for mandatory control interface) */
|
||||
#define AUDIO_INTERFACES (INPUT_INTERFACES + OUTPUT_INTERFACES + 1)
|
||||
@@ -365,7 +368,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
ID_CLKSEL, /* 7 bCSourceID: ID of Clock Entity */
|
||||
NUM_USB_CHAN_OUT, /* 8 bNrChannels */
|
||||
0,0,0,0, /* 9 bmChannelConfig */
|
||||
13, /* 13 iChannelNames */
|
||||
15, /* 13 iChannelNames */
|
||||
0x00, 0x00, /* 14 bmControls */
|
||||
6, /* 16 iTerminal */
|
||||
|
||||
@@ -484,7 +487,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
ID_CLKSEL, /* 7 bCSourceID: ID of Clock Entity */
|
||||
NUM_USB_CHAN_IN, /* 8 bNrChannels */
|
||||
0,0,0,0, /* 9 bmChannelConfig */
|
||||
31, /* 13 iChannelNames */
|
||||
33, /* 13 iChannelNames */
|
||||
0x00, 0x00, /* 14 bmControls */
|
||||
0, /* 16 iTerminal */
|
||||
|
||||
@@ -604,7 +607,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
2, /* 6 bNrPins */
|
||||
ID_IT_USB, /* 7 baSourceId(1) */
|
||||
ID_IT_AUD, /* 7 baSourceId(2) */
|
||||
MIX_INPUTS, /* 8+p bNrChannels */
|
||||
MIX_INPUTS, /* 8+p bNrChannels */
|
||||
0, /* 9+p bmChannelConfig */
|
||||
0, /* 10+p bmChannelConfig */
|
||||
0, /* 11+p bmChannelConfig */
|
||||
@@ -621,20 +624,72 @@ unsigned char cfgDesc_Audio2[] =
|
||||
/* N = 144 (18 * 8) */
|
||||
/* Mixer Unit Bitmap - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff */
|
||||
0x0D+0x01+0x12, /* 0 bLength : 13 + num inputs + bit map (inputs * outputs) */
|
||||
MIXER_LENGTH, /* 0 bLength : 13 + num inputs + bit map (inputs * outputs) */
|
||||
CS_INTERFACE, /* 1 bDescriptorType: 0x24 */
|
||||
0x04, /* bDescriptorSubtype: MIXER_UNIT */
|
||||
ID_MIXER_1, /* Mixer unit id */
|
||||
0x01, /* Number of input pins */
|
||||
ID_XU_MIXSEL, /* Connected terminal or unit id for input pin*/
|
||||
0x08, /* Number of mixer output channels */
|
||||
ID_XU_MIXSEL, /* Connected terminal or unit id for input pin*/
|
||||
MAX_MIX_COUNT, /* Number of mixer output channels */
|
||||
0x00, 0x00, 0x00, 0x00, /* Spacial location ???? */
|
||||
49, /* Channel name index */
|
||||
0xff, 0xff, 0xff, 0xff, /* Mixer programmable control bitmap */
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff,
|
||||
49, /* Channel name index */
|
||||
#if MIX_BMCONTROLS_LEN > 0 /* Mixer programmable control bitmap */
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 1
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 2
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 3
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 4
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 5
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 6
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 7
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 8
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 9
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 10
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 11
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 12
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 13
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 14
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 15
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 16
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 17
|
||||
0xff,
|
||||
#endif
|
||||
#if MIX_BMCONTROLS_LEN > 18
|
||||
#error unxpected BMCONTROLS_LEN
|
||||
#endif
|
||||
0x00, /* bmControls */
|
||||
0, /* Mixer unit string descriptor index */
|
||||
#endif
|
||||
@@ -680,7 +735,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
0x00, /* 4 bmControls */
|
||||
0x01, /* 5 bFormatType */
|
||||
PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */
|
||||
NUM_USB_CHAN_OUT, /* 11 bNrChannels */
|
||||
NUM_USB_CHAN_OUT, /* 11 bNrChannels */
|
||||
0,0,0,0, /* 12:14: bmChannelConfig */
|
||||
13, /* 15 iChannelNames */
|
||||
|
||||
@@ -715,7 +770,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
|
||||
17, /* 3 bmAttributes (bitmap) */
|
||||
4,0, /* 4 wMaxPacketSize */
|
||||
8, /* 6 bInterval */
|
||||
4, /* 6 bInterval. Only values <= 1 frame (8) supported by MS */
|
||||
|
||||
#ifdef ADAT_TX
|
||||
/* Standard AS Interface Descriptor (4.9.1) (Alt) */
|
||||
@@ -739,7 +794,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */
|
||||
NUM_USB_CHAN_OUT, /* 11 bNrChannels */
|
||||
0,0,0,0, /* 12:14: bmChannelConfig */
|
||||
13, /* 15 iChannelNames */
|
||||
15, /* 15 iChannelNames */
|
||||
|
||||
/* Type 1 Format Type Descriptor */
|
||||
0x06, /* 0 bLength (in bytes): 6 */
|
||||
@@ -810,7 +865,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */
|
||||
NUM_USB_CHAN_IN, /* 11 bNrChannels */
|
||||
0,0,0,0, /* 12:14: bmChannelConfig */
|
||||
31, /* 15 iChannelNames */
|
||||
33, /* 15 iChannelNames */
|
||||
|
||||
/* Type 1 Format Type Descriptor */
|
||||
0x06, /* 0 bLength (in bytes): 6 */
|
||||
@@ -859,7 +914,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */
|
||||
NUM_USB_CHAN_IN - 4, /* 11 bNrChannels */
|
||||
0,0,0,0, /* 12:14: bmChannelConfig */
|
||||
31, /* 15 iChannelNames */
|
||||
33, /* 15 iChannelNames */
|
||||
|
||||
/* Type 1 Format Type Descriptor */
|
||||
0x06, /* 0 bLength (in bytes): 6 */
|
||||
@@ -998,7 +1053,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
0x02, /* 2 bDescriptorSubtype : MIDI_IN_JACK subtype. (field size 1 bytes) */
|
||||
0x02, /* 3 bJackType : EXTERNAL. (field size 1 bytes) */
|
||||
0x02, /* 4 bJackID : ID of this Jack. (field size 1 bytes) */
|
||||
0x00, /* 5 iJack : Unused. (field size 1 bytes) */
|
||||
0x14, /* 5 iJack : Unused. (field size 1 bytes) */
|
||||
|
||||
/* Table B-9: MIDI Adapter MIDI OUT Jack Descriptor (Embedded) */
|
||||
0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
|
||||
@@ -1020,7 +1075,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
0x01, /* 5 bNrInputPins : Number of Input Pins of this Jack. (field size 1 bytes) */
|
||||
0x01, /* 6 BaSourceID(1) : ID of the Entity to which this Pin is connected. (field size 1 bytes) */
|
||||
0x01, /* 7 BaSourcePin(1) : Output Pin number of the Entity to which this Input Pin is connected. */
|
||||
0x00, /* 8 iJack : Unused. (field size 1 bytes) */
|
||||
0x13, /* 8 iJack : Unused. (field size 1 bytes) */
|
||||
|
||||
/* Table B-11: MIDI Adapter Standard Bulk OUT Endpoint Descriptor */
|
||||
0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
|
||||
@@ -1068,17 +1123,31 @@ unsigned char cfgDesc_Audio2[] =
|
||||
0x00, /* 4 bNumEndpoints : 0 endpoints. (field size 1 bytes) */
|
||||
0xFE, /* 5 bInterfaceClass : DFU. (field size 1 bytes) */
|
||||
0x01, /* 6 bInterfaceSubclass : (field size 1 bytes) */
|
||||
0x00, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */
|
||||
12, /* 8 iInterface : Used. (field size 1 bytes) */
|
||||
0x01, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */
|
||||
8, /* 8 iInterface : Used. (field size 1 bytes) */
|
||||
|
||||
/* Standard DFU class functional descriptor */
|
||||
0x07,
|
||||
#if 0
|
||||
/* DFU 1.0 Run-Time DFU Functional Descriptor */
|
||||
0x07,
|
||||
0x21,
|
||||
0x07,
|
||||
0xFA,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
#else
|
||||
/* DFU 1.1 Run-Time DFU Functional Descriptor */
|
||||
0x09, /* 0 Size */
|
||||
0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */
|
||||
0x07, /* 2 bmAttributes */
|
||||
0xFA, /* 3 wDetachTimeOut */
|
||||
0x00, /* 4 wDetachTimeOut */
|
||||
0x40, /* 5 wTransferSize */
|
||||
0x00, /* 6 wTransferSize */
|
||||
0x10, /* 7 bcdDFUVersion */
|
||||
0x01, /* 7 bcdDFUVersion */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef IAP
|
||||
@@ -1092,7 +1161,7 @@ unsigned char cfgDesc_Audio2[] =
|
||||
0xFF, /* 5 bInterfaceClass : DFU. (field size 1 bytes) */
|
||||
0xF0, /* 6 bInterfaceSubclass : (field size 1 bytes) */
|
||||
0x00, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */
|
||||
57, /* 8 iInterface : Used. (field size 1 bytes) */
|
||||
59, /* 8 iInterface : Used. (field size 1 bytes) */
|
||||
|
||||
/* iAP Bulk OUT Endpoint Descriptor */
|
||||
0x07, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
|
||||
@@ -1145,6 +1214,9 @@ static unsigned char strDescs_Audio2[][40] =
|
||||
APPEND_VENDOR_STR(S/PDIF Clock), // 10 iClockSource
|
||||
APPEND_VENDOR_STR(ADAT Clock), // 11 iClockSource
|
||||
APPEND_VENDOR_STR(DFU), // 12 iInterface for DFU interface
|
||||
|
||||
APPEND_VENDOR_STR(MIDI Out),
|
||||
APPEND_VENDOR_STR(MIDI In ),
|
||||
|
||||
"Analogue 1", // 13 Output channel name place holders - Get customised at runtime based on device config
|
||||
"Analogue 2", // 14
|
||||
@@ -1257,7 +1329,7 @@ unsigned char oSpeedCfgDesc[] =
|
||||
#define STREAMING_INTERFACES (INPUT_INTERFACES + OUTPUT_INTERFACES)
|
||||
|
||||
|
||||
#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES * 61) + (OUTPUT_INTERFACES * 70) + (DFU_INTERFACES * 16))
|
||||
#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES * 61) + (OUTPUT_INTERFACES * 70) + (DFU_INTERFACES * 18))
|
||||
#ifdef AUDIO_CLASS_FALLBACK
|
||||
unsigned char cfgDesc_Audio1[] =
|
||||
{
|
||||
@@ -1536,19 +1608,19 @@ unsigned char cfgDesc_Audio1[] =
|
||||
0x00, 0x00, /* Unused */
|
||||
|
||||
#endif
|
||||
#ifdef DFU
|
||||
/* Standard DFU class Interface descriptor */
|
||||
0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
|
||||
0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */
|
||||
(INPUT_INTERFACES+OUTPUT_INTERFACES+1), /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */
|
||||
(INPUT_INTERFACES+OUTPUT_INTERFACES+1), /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */
|
||||
0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */
|
||||
0x00, /* 4 bNumEndpoints : 0 endpoints. (field size 1 bytes) */
|
||||
0xFE, /* 5 bInterfaceClass : DFU. (field size 1 bytes) */
|
||||
0x01, /* 6 bInterfaceSubclass : (field size 1 bytes) */
|
||||
0x00, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */
|
||||
0x08, /* 8 iInterface : Unused. (field size 1 bytes) */
|
||||
0x01, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */
|
||||
12, /* 8 iInterface : Unused. (field size 1 bytes) */
|
||||
|
||||
/* Standard DFU class functional descriptor */
|
||||
#if 0
|
||||
/* DFU 1.0 Run-Time DFU Functional Descriptor */
|
||||
0x07,
|
||||
0x21,
|
||||
0x07,
|
||||
@@ -1556,6 +1628,18 @@ unsigned char cfgDesc_Audio1[] =
|
||||
0x00,
|
||||
0x40,
|
||||
0x00
|
||||
#else
|
||||
/* DFU 1.1 Run-Time DFU Functional Descriptor */
|
||||
0x09, /* 0 Size */
|
||||
0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */
|
||||
0x07, /* 2 bmAttributes */
|
||||
0xFA, /* 3 wDetachTimeOut */
|
||||
0x00, /* 4 wDetachTimeOut */
|
||||
0x40, /* 5 wTransferSize */
|
||||
0x00, /* 6 wTransferSize */
|
||||
0x10, /* 7 bcdDFUVersion */
|
||||
0x01, /* 7 bcdDFUVersion */
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "dfu_types.h"
|
||||
#include "xc_ptr.h"
|
||||
|
||||
/* Windows does not have a built in DFU driver (windows will prompt), so warn that DFU will not be functional in Audio 1.0 mode.
|
||||
/* Windows does not have a built in DFU driver (windows will prompt), so warn that DFU will not be functional in Audio 1.0 mode.Udi
|
||||
* Of course, OSX is unaffected.
|
||||
*/
|
||||
#if ((AUDIO_CLASS==1) || defined(AUDIO_CLASS_FALLBACK)) && defined(DFU)
|
||||
@@ -70,9 +70,12 @@ short mixer1Weights[18*8];
|
||||
//#define MAX_MIX_COUNT 8
|
||||
|
||||
unsigned char channelMap[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT];
|
||||
#if NUM_USB_CHAN_OUT > 0
|
||||
unsigned char channelMapAud[NUM_USB_CHAN_OUT];
|
||||
#endif
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
unsigned char channelMapUsb[NUM_USB_CHAN_IN];
|
||||
|
||||
#endif
|
||||
unsigned char mixSel[MIX_INPUTS];
|
||||
#endif
|
||||
|
||||
@@ -180,16 +183,20 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
mixer1Weights[54] = 0;
|
||||
mixer1Weights[63] = 0;
|
||||
|
||||
#if NUM_USB_CHAN_OUT > 0
|
||||
/* Setup up audio output channel mapping */
|
||||
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
|
||||
{
|
||||
channelMapAud[i] = i;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NUM_USB_CHAN_IN > 0
|
||||
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
|
||||
{
|
||||
channelMapUsb[i] = i + NUM_USB_CHAN_OUT;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Set up channel mapping default */
|
||||
@@ -223,33 +230,33 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
/* Build up channel string table - By default all channels are marked as analogue
|
||||
* TODO We really want to do this an build time... */
|
||||
#if defined(SPDIF_RX) && (SPDIF_RX_INDEX != 0)
|
||||
safestrcpy(strDescs_Audio2[SPDIF_RX_INDEX + 31], "S/PDIF 1");
|
||||
safestrcpy(strDescs_Audio2[SPDIF_RX_INDEX + 32], "S/PDIF 2");
|
||||
safestrcpy(strDescs_Audio2[SPDIF_RX_INDEX + 33], "S/PDIF 1");
|
||||
safestrcpy(strDescs_Audio2[SPDIF_RX_INDEX + 34], "S/PDIF 2");
|
||||
#endif
|
||||
#if defined(ADAT_RX) && (ADAT_RX_INDEX != 0)
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 31], "ADAT 1");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 32], "ADAT 2");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 33], "ADAT 3");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 34], "ADAT 4");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 35], "ADAT 5");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 36], "ADAT 6");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 37], "ADAT 7");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 38], "ADAT 8");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 33], "ADAT 1");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 34], "ADAT 2");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 35], "ADAT 3");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 36], "ADAT 4");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 37], "ADAT 5");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 38], "ADAT 6");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 39], "ADAT 7");
|
||||
safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + 40], "ADAT 8");
|
||||
#endif
|
||||
|
||||
#if defined(SPDIF) && (SPDIF_TX_INDEX != 0) /* "Analogue naming gets priority */
|
||||
safestrcpy(strDescs_Audio2[SPDIF_TX_INDEX + 13], "S/PDIF 1");
|
||||
safestrcpy(strDescs_Audio2[SPDIF_TX_INDEX + 14], "S/PDIF 2");
|
||||
safestrcpy(strDescs_Audio2[SPDIF_TX_INDEX + 15], "S/PDIF 1");
|
||||
safestrcpy(strDescs_Audio2[SPDIF_TX_INDEX + 16], "S/PDIF 2");
|
||||
#endif
|
||||
#if defined(ADAT_TX) && (ADAT_TX_INDEX != 0)
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 13], "ADAT 1");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 14], "ADAT 2");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 15], "ADAT 3");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 16], "ADAT 4");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 17], "ADAT 5");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 18], "ADAT 6");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 19], "ADAT 7");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 20], "ADAT 8");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 15], "ADAT 1");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 16], "ADAT 2");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 17], "ADAT 3");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 18], "ADAT 4");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 19], "ADAT 5");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 20], "ADAT 6");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 21], "ADAT 7");
|
||||
safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + 22], "ADAT 8");
|
||||
#endif
|
||||
|
||||
#ifdef VENDOR_AUDIO_REQS
|
||||
@@ -494,7 +501,6 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
// Handshake
|
||||
//chkct(c_audioControl, XS1_CT_END);
|
||||
|
||||
//printint(8);
|
||||
break;
|
||||
|
||||
#endif
|
||||
@@ -736,7 +742,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
device_reboot();
|
||||
}
|
||||
|
||||
/* TODO we should not make the assumtion that all DFU requests are handled */
|
||||
/* TODO we should not make the assumption that all DFU requests are handled */
|
||||
retVal = 0;
|
||||
}
|
||||
/* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first
|
||||
@@ -748,6 +754,7 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
|| (request == CLASS_ENDPOINT_REQUEST && ((interfaceNum == 0x82) || (interfaceNum == 0x01))))
|
||||
{
|
||||
#endif
|
||||
|
||||
#if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK)
|
||||
if(g_curUsbSpeed == XUD_SPEED_HS)
|
||||
{
|
||||
@@ -780,7 +787,6 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: STALL
|
||||
//printstr("unrecognised request\n");
|
||||
//printhexln(sp.bRequest);
|
||||
//printhexln(sp.bmRequestType.Type);
|
||||
@@ -802,7 +808,9 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
transfer, and the STALL condition terminates at the beginning of the
|
||||
next control transfer (Setup). The remainder of this section refers to
|
||||
the general case of a functional stall */
|
||||
//XUD_ProtocolStall(ep0_out, ep0_in):
|
||||
XUD_SetStall_Out(0);
|
||||
XUD_SetStall_In(0);
|
||||
|
||||
}
|
||||
|
||||
if (retVal < 0)
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
|
||||
// Channel interface
|
||||
void I2cRegWriteC(int deviceAdrs, int Adrs, int WrData, chanend c);
|
||||
|
||||
int I2cRegReadC(int deviceAdrs, int Adrs, chanend c);
|
||||
|
||||
// Function interface
|
||||
void I2cRegWrite(int deviceAdrs, int Adrs, int WrData, port AUD_SCLK, port AUD_SDIN);
|
||||
|
||||
int I2cRegRead(int deviceAdrs, int Adrs, port AUD_SCLK, port AUD_SDIN);
|
||||
|
||||
@@ -1,28 +1,6 @@
|
||||
#include <xs1.h>
|
||||
#include <print.h>
|
||||
|
||||
int I2cRegReadC(int device, int addr, chanend c) {
|
||||
int read;
|
||||
int retVal;
|
||||
c <: 0; // isWrite
|
||||
c <: device;
|
||||
c <: addr;
|
||||
c <: 1; // only ever one byte
|
||||
c :> read;
|
||||
c :> retVal;
|
||||
return read;
|
||||
}
|
||||
|
||||
void I2cRegWriteC(int device, int addr, int data, chanend c) {
|
||||
int retVal;
|
||||
c <: 1; // isWrite
|
||||
c <: device;
|
||||
c <: addr;
|
||||
c <: 1; // only ever one byte
|
||||
c <: data;
|
||||
c :> retVal;
|
||||
}
|
||||
|
||||
int I2cRegRead(int device, int addr, port scl, port sda)
|
||||
{
|
||||
//int Result;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
void PllInit(chanend c);
|
||||
void PllInit(void);
|
||||
|
||||
|
||||
void PllMult(unsigned mult, chanend c);
|
||||
void PllMult(unsigned mult);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <xs1.h>
|
||||
#include <print.h>
|
||||
#include <assert.h>
|
||||
#include "xc_ptr.h"
|
||||
#define NO_INLINE_MIDI_SELECT_HANDLER 1
|
||||
#include "usb_midi.h"
|
||||
@@ -58,11 +57,8 @@ inline void XUD_Change_ReadyIn_Buffer(XUD_ep e, unsigned bufferPtr, int len)
|
||||
#define BUFF_SIZE_OUT MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_OUT, 4 * CLASS_ONE_PACKET_SIZE * MAX_CLASS_ONE_CHAN)
|
||||
#define BUFF_SIZE_IN MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_IN, 4 * CLASS_ONE_PACKET_SIZE * MAX_CLASS_ONE_CHAN)
|
||||
#define MAX_USB_AUD_PACKET_SIZE 1028
|
||||
//#define OUT_BUFFER_PREFILL (2*4*BUFF_SIZE_OUT/3)
|
||||
//#define OUT_BUFFER_PREFILL MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2
|
||||
//#define IN_BUFFER_PREFILL MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2
|
||||
#define OUT_BUFFER_PREFILL (MAX(MAX_CLASS_ONE_CHAN*CLASS_ONE_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*CLASS_TWO_PACKET_SIZE*4+4)*1)
|
||||
#define IN_BUFFER_PREFILL (MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2)
|
||||
#define NUM_PACKETS_PREFILL (1)
|
||||
|
||||
//#pragma xta command "add exclusion out_underflow"
|
||||
//#pragma xta command "add exclusion freq_change"
|
||||
//#pragma xta command "add exclusion print_err"is_as
|
||||
@@ -93,6 +89,9 @@ unsigned audioBuffIn[BUFF_SIZE_IN + (MAX_DEVICE_AUD_PACKET_SIZE>>2) + 4];
|
||||
|
||||
unsigned inZeroBuff[(MAX_DEVICE_AUD_PACKET_SIZE>>2)+4];
|
||||
|
||||
unsigned g_in_buffer_prefill = 0;
|
||||
unsigned g_out_buffer_prefill = 0;
|
||||
|
||||
unsigned ledVal = 1;
|
||||
unsigned dir = 0;
|
||||
|
||||
@@ -139,6 +138,41 @@ void led(chanend ?c_led)
|
||||
|
||||
void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max);
|
||||
|
||||
|
||||
|
||||
/* This function sets the prefill levels for the in and out buffers,
|
||||
it needs to be changed for a different sample rate or number of channels.
|
||||
The amount set here is what determines the latency of the buffering.
|
||||
*/
|
||||
static void set_prefills(unsigned int sampFreq)
|
||||
{
|
||||
int usb_speed;
|
||||
unsigned prefill;
|
||||
int bytes_per_sample;
|
||||
int num_channels;
|
||||
int frame;
|
||||
int packet_size;
|
||||
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
|
||||
|
||||
frame = usb_speed == XUD_SPEED_HS ? 8000 : 1000;
|
||||
packet_size = ((((sampFreq+frame-1)/frame))+3);
|
||||
|
||||
bytes_per_sample = usb_speed == XUD_SPEED_HS ? 4 : 3;
|
||||
|
||||
GET_SHARED_GLOBAL(num_channels, g_numUsbChanOut);
|
||||
prefill = ((packet_size * num_channels * bytes_per_sample + 4) * NUM_PACKETS_PREFILL);
|
||||
SET_SHARED_GLOBAL(g_out_buffer_prefill, prefill);
|
||||
|
||||
GET_SHARED_GLOBAL(num_channels, g_numUsbChanIn);
|
||||
prefill = ((packet_size * num_channels * bytes_per_sample + 4) * NUM_PACKETS_PREFILL);
|
||||
SET_SHARED_GLOBAL(g_in_buffer_prefill, prefill);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(MIDI) || defined(IAP)
|
||||
static inline void swap(xc_ptr &a, xc_ptr &b)
|
||||
{
|
||||
xc_ptr tmp;
|
||||
@@ -147,6 +181,7 @@ static inline void swap(xc_ptr &a, xc_ptr &b)
|
||||
b = tmp;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// shared global midi buffering variables
|
||||
#ifdef MIDI
|
||||
@@ -283,6 +318,15 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
|
||||
if (space_left > (BUFF_SIZE_IN*4/2))
|
||||
{
|
||||
inOverflow = 0;
|
||||
// When we come out of overflow we clear the buffer and
|
||||
// go into underflow and do a prefill again - this is to
|
||||
// get a low latency and to ensure consistency between
|
||||
// coming out of underflow or overflow
|
||||
inUnderflow = 1;
|
||||
SET_SHARED_GLOBAL(g_aud_to_host_rdptr,
|
||||
aud_to_host_fifo_start);
|
||||
SET_SHARED_GLOBAL(g_aud_to_host_wrptr,
|
||||
aud_to_host_fifo_start);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -370,6 +414,7 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
|
||||
|
||||
if(outUnderflow)
|
||||
{
|
||||
unsigned prefill;
|
||||
#pragma xta endpoint "out_underflow"
|
||||
/* We're still pre-buffering, send out 0 samps */
|
||||
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
|
||||
@@ -384,8 +429,9 @@ void handle_audio_request(chanend c_mix_out, chanend ?c_led)
|
||||
outSamps += BUFF_SIZE_OUT*4;
|
||||
}
|
||||
|
||||
GET_SHARED_GLOBAL(prefill, g_out_buffer_prefill);
|
||||
/* If we have a decent number of samples, come out of underflow cond */
|
||||
if (outSamps >= (OUT_BUFFER_PREFILL))
|
||||
if (outSamps >= prefill)
|
||||
{
|
||||
outUnderflow = 0;
|
||||
}
|
||||
@@ -799,6 +845,8 @@ void decouple(chanend c_mix_out,
|
||||
}
|
||||
#endif
|
||||
|
||||
set_prefills(sampFreq);
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (!isnull(c_clk_int))
|
||||
@@ -854,13 +902,14 @@ void decouple(chanend c_mix_out,
|
||||
SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start);
|
||||
SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start);
|
||||
SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0);
|
||||
|
||||
/* Wait for handshake back and pass back up */
|
||||
chkct(c_mix_out, XS1_CT_END);
|
||||
|
||||
SET_SHARED_GLOBAL(g_freqChange, 0);
|
||||
asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
|
||||
|
||||
set_prefills(sampFreq);
|
||||
|
||||
ENABLE_INTERRUPTS();
|
||||
|
||||
speedRem = 0;
|
||||
@@ -883,6 +932,7 @@ void decouple(chanend c_mix_out,
|
||||
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
|
||||
|
||||
SET_SHARED_GLOBAL(g_freqChange, 0);
|
||||
set_prefills(sampFreq);
|
||||
ENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
@@ -959,9 +1009,22 @@ void decouple(chanend c_mix_out,
|
||||
if (space_left >= (BUFF_SIZE_OUT*4/2))
|
||||
{
|
||||
/* Come out of OUT overflow state */
|
||||
outOverflow = 0;
|
||||
DISABLE_INTERRUPTS();
|
||||
outOverflow = 0;
|
||||
// When we come out of overflow we clear the buffer and
|
||||
// go into underflow and do a prefill again - this is to
|
||||
// get a low latency and to ensure consistency between
|
||||
// coming out of underflow or overflow
|
||||
outUnderflow = 1;
|
||||
SET_SHARED_GLOBAL(g_aud_from_host_rdptr,
|
||||
aud_from_host_fifo_start);
|
||||
SET_SHARED_GLOBAL(g_aud_from_host_wrptr,
|
||||
aud_from_host_fifo_start);
|
||||
SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0);
|
||||
|
||||
SET_SHARED_GLOBAL(g_aud_from_host_buffer, aud_from_host_wrptr);
|
||||
XUD_SetReady(aud_from_host_usb_ep, 1);
|
||||
ENABLE_INTERRUPTS();
|
||||
#ifdef DEBUG_LEDS
|
||||
led(c_led);
|
||||
#endif
|
||||
@@ -988,6 +1051,7 @@ void decouple(chanend c_mix_out,
|
||||
int aud_to_host_wrptr;
|
||||
int aud_to_host_rdptr;
|
||||
int fill_level;
|
||||
unsigned prefill;
|
||||
GET_SHARED_GLOBAL(aud_to_host_wrptr, g_aud_to_host_wrptr);
|
||||
GET_SHARED_GLOBAL(aud_to_host_rdptr, g_aud_to_host_rdptr);
|
||||
|
||||
@@ -997,7 +1061,8 @@ void decouple(chanend c_mix_out,
|
||||
if (fill_level < 0)
|
||||
fill_level += BUFF_SIZE_IN*4;
|
||||
|
||||
if (fill_level >= IN_BUFFER_PREFILL)
|
||||
GET_SHARED_GLOBAL(prefill, g_in_buffer_prefill);
|
||||
if (fill_level >= prefill)
|
||||
{
|
||||
inUnderflow = 0;
|
||||
SET_SHARED_GLOBAL(g_aud_to_host_buffer, aud_to_host_rdptr);
|
||||
|
||||
Reference in New Issue
Block a user