一:<略>
二:按照2ch-in,2ch-out循诉,DSD out横辆,修改的audioin_deliver()的部分內(nèi)容
{
#if (I2S_CHANS_ADC != 0)
/* Input previous L sample into L in buffer */
/* First input (i.e. frameCount == 0) we read last ADC channel ofprevious frame.. */
unsigned buffIndex = !readBuffNo;
#pragma loop unroll
{ // p_i2s_adc[0] :> sample;
// Manual IN instruction sincecompiler generates an extra setc per IN (bug #15256)
asm volatile("in %0,res[%1]" : "=r"(sample) :"r"(p_i2s_adc[0]));
tempsample=bitrev(sample);
/* Note the use of readBuffNochanges based on frameCount */
if(buffIndex)
samplesIn_1[0] =tempsample;//bitrev(sample); // channels 0, 2, 4.. on each line.
else
samplesIn_0[0] =tempsample;//bitrev(sample);
}
#endif
xscope_int(PLVALUE,tempsample);
/* LR clock delayed by one clock, This is so MSB is output on thefalling edge of BCLK
* after the falling edge on which LRCLK was toggled. (see I2S spec) */
p_lrclk <: 0x80000000;/* Generate clocks LR Clock low - LEFT */
#pragma xta endpoint "i2s_output_l"
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
#pragma loop unroll
/* Output "even" channel to DAC (i.e. left) */
{
p_i2s_dac[0] <:bitrev(samplesOut[0]);
}
#endif
doI2SClocks(divide);/* Clock out the LR Clock, the DAC data and Clock inthe next sample into ADC */
#if (I2S_CHANS_ADC != 0)
/* Channels 0, 2, 4.. on each line */
#pragma loop unroll
{
/* Manual IN instruction since compiler generates an extra setc per IN(bug #15256) */
asm volatile("in %0,res[%1]" : "=r"(sample) :"r"(p_i2s_adc[0]));
tempsample=bitrev(sample);
if(buffIndex)
samplesIn_1[1] = tempsample;//bitrev(sample);// channels 1, 3, 5.. on each line.
else
samplesIn_0[1] =tempsample;//bitrev(sample); // channels 1, 3, 5.. on each line.
}
#endif
xscope_int(PRVALUE,tempsample);
p_lrclk <: 0x7FFFFFFF;/* Generateclocks LR Clock high - RIGHT */
#pragma xta endpoint "i2s_output_r"
#if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0)
/* Output "odd" channel to DAC (i.e. right) */
#pragma loop unroll
{
p_i2s_dac[0] <:bitrev(samplesOut[1]);
}
#endif
doI2SClocks(divide);
} // !dsdMode
三:進(jìn)一步的修改:去掉不必要的預(yù)編譯,用循環(huán)代替類似段
(1)#pragma loop unroll命令茄猫,編譯器在進(jìn)行編譯時(shí)狈蚤,遇到該命令就會對循環(huán)進(jìn)行展開。
由于已經(jīng)去掉循環(huán)划纽,因此可將這一條預(yù)編譯命令去掉脆侮。
(2)#pragma xtaendpoint "i2s_output_r" ,xta是另一種芯片勇劣,帶ARM核靖避,因此可去掉。
(3)用循環(huán)表示左右聲道的處理比默,將類似的兩段代碼寫成一段幻捏,注意用#pragma loop unroll預(yù)編譯指令展開
(4)用了兩個(gè)數(shù)組(samplesIn_1[],samplesIn_0[])來存儲錄音數(shù)據(jù),注意從I2S讀入的是一個(gè)數(shù)組命咐,而DoSampleTransfer中用的是另一個(gè)數(shù)組篡九。
{
int i=0;
#pragma loop unroll //預(yù)編譯命令,將下面循環(huán)展開
for(i=0;i<2;i++) //i=0: even channel left;i=1:odd channelright.
{
/* Input previous Lsample into L in buffer */
/* First input (i.e.frameCount == 0) we read last ADC channel of previous frame.. */
unsigned buffIndex = !readBuffNo;//(frameCount< 3) ? !readBuffNo : readBuffNo;
// p_i2s_adc[0] :>sample;
// Manual IN instructionsince compiler generates an extra setc per IN (bug #15256)
asm volatile("in %0,res[%1]" : "=r"(sample) : "r"(p_i2s_adc[0]));
tempsample=bitrev(sample);
/* Note the use ofreadBuffNo changes based on frameCount */
if(buffIndex)0
samplesIn_1[i] = tempsample;//bitrev(sample);
else
samplesIn_0[i] =tempsample;//bitrev(sample);
/* LR clock delayed byone clock, This is so MSB is output on the falling edge of BCLK
* after the falling edge on which LRCLK wastoggled. (see I2S spec) */
if(i==0)
{
xscope_int(PLVALUE,tempsample);
p_lrclk <: 0x80000000;/* Generateclocks LR Clock low - LEFT */
}
else if(i==1)
{
xscope_int(PRVALUE,tempsample);
p_lrclk <: 0x7FFFFFFF;/* Generate clocks LR Clock high - RIGHT */
}
p_i2s_dac[0] <: bitrev(samplesOut[i]); //下一小節(jié):第四部分修改之處。
/* Clock out the LR Clock, the DAC data and Clock in the nextsample into ADC */
doI2SClocks(divide);
} //end for(i=0;i<2;i++)
}
{
/* Do samples transfer */
/* The below looks a bit odd but forces thecompiler to inline twice */
unsigned command;
if(readBuffNo)
command =DoSampleTransfer(c_out, 1, underflowWord);
else
command = DoSampleTransfer(c_out,0, underflowWord);
if(command)
{
return command;
}
/* Reset frame counterand flip the ADC buffer */
frameCount = 0;
readBuffNo = !readBuffNo;
}
四:從ADC獲取數(shù)據(jù)直接發(fā)給DAC醋奠,實(shí)現(xiàn)監(jiān)聽
將上面代碼中的這一句:
? p_i2s_dac[0] <:bitrev(samplesOut[i]);
改為:
? p_i2s_dac[0] <: bitrev(tempsample);//即用收到的數(shù)據(jù)直接放到I2S
實(shí)現(xiàn)監(jiān)聽榛臼,但須注意的是切換到聽歌狀態(tài)時(shí)伊佃,不能聽WAV歌曲,可以聽DSD讽坏,原因是聽歌狀態(tài)的DAC路徑被截?cái)嗔硕АT谡巾?xiàng)目時(shí)還需要改變成兩種狀態(tài)可切換。
五:連接android 華為手機(jī)
華為手機(jī)H60-l01路呜,Android 4.4.2迷捧,(1)支持OTG,(2)安裝海貝無損音樂播放器胀葱,用兩個(gè)小頭的USB連接后可以實(shí)現(xiàn)聽音樂功能漠秋。