1 | // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
2 | //
|
3 | // Purpose.............: UOAudio
|
4 | // Author..............: §(&$%/&%§/"&%§$/&%
|
5 | // Created.............: 06.12.2011
|
6 | // Copyright...........: ©2011
|
7 | // Notes...............:
|
8 | // Changes.............:
|
9 | // To Do...............:
|
10 | //
|
11 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
12 |
|
13 | #include "UOAudio.h"
|
14 | #include "UOIOPorts.h"
|
15 |
|
16 | extern volatile int pbClk; // the PB frequency
|
17 |
|
18 | static short audioBuffer1[2*audioBufferSize]; //2 channels 2 buffers
|
19 | static short audioBuffer2[2*audioBufferSize]; //2 channels 2 buffers
|
20 | static short *audioCurBuffer;
|
21 | static short *audioCurBufferEnd;
|
22 | static int audioSamplesToPlay;
|
23 | static short audioBufferSelect;
|
24 |
|
25 | static UOAudioReplayProcT audioReplayProc = 0;
|
26 | static void* audioCustomData;
|
27 | int audioCustomDataPosition;
|
28 | int audioCustomDataPositionStep;
|
29 |
|
30 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
31 |
|
32 | short UOAudioIsPlaying( void )
|
33 | {
|
34 | return audioReplayProc != 0;
|
35 | }
|
36 |
|
37 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
38 |
|
39 | void UOAudioReplayProc8BitMono( short* p, int len, void *pData )
|
40 | {
|
41 | int i;
|
42 |
|
43 | for( i = 0;i < len;++i )
|
44 | {
|
45 | *p = ((char*)pData)[audioCustomDataPosition>>8]<<8;
|
46 | *(p+1) = ((char*)pData)[audioCustomDataPosition>>8]<<8;
|
47 | p += 2;
|
48 | audioCustomDataPosition += audioCustomDataPositionStep;
|
49 | }
|
50 |
|
51 | }
|
52 |
|
53 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
54 |
|
55 | void UOAudioInit( void )
|
56 | {
|
57 | #ifndef _Windows
|
58 | UOTrisDClr = BIT_2;
|
59 |
|
60 | // init software irq for fill buffer
|
61 | INTSetVectorPriority( INT_CORE_SOFTWARE_0_VECTOR, INT_PRIORITY_LEVEL_1 );
|
62 | INTSetVectorSubPriority( INT_CORE_SOFTWARE_0_VECTOR, INT_SUB_PRIORITY_LEVEL_1 );
|
63 | INTClearFlag(INT_CS0);
|
64 | INTEnable(INT_CS0, INT_ENABLED);
|
65 |
|
66 | audioCustomDataPositionStep = (1<<8)/8;
|
67 | #endif
|
68 | }
|
69 |
|
70 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
71 |
|
72 | void UOAudioStart( void )
|
73 | {
|
74 | #ifndef _Windows
|
75 | SpiChnOpen(SPI_CHANNEL1, SPI_CON_MODE16|SPI_CON_ON|SPI_CON_MSTEN|SPI_OPEN_CKP_HIGH , 40);
|
76 | // set up master clock to 5,6448 mhz
|
77 | // 80 mhz / 5,6448 mhz mclk
|
78 |
|
79 |
|
80 | /* Enable OC | 32 bit Mode | Timer2 is selected | Continuous O/P | OC Pin High , S Compare value, Compare value*/
|
81 | UOHWDacMClkOC( OC_ON | OC_TIMER_MODE16 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH , 0, 80E6/5644800/2 );
|
82 |
|
83 |
|
84 | // set up LRCIN
|
85 | OpenTimer4( T4_ON, 80E6/(44642*2) );
|
86 | OpenTimer2(T2_ON, 80E6/(5644800)/2 );
|
87 | mT4SetIntPriority( 7 );
|
88 | mT4ClearIntFlag();
|
89 | mT4IntEnable( 1 );
|
90 | TMR4 = 0;
|
91 | TMR2 = 0;
|
92 | #endif
|
93 | }
|
94 |
|
95 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
96 |
|
97 | void UOAudioStop( void )
|
98 | {
|
99 | #ifndef _Windows
|
100 | SpiChnClose( SPI_CHANNEL1 );
|
101 | UOHWDacMClkOClose();
|
102 | CloseTimer4();
|
103 | CloseTimer2();
|
104 | audioReplayProc = 0;
|
105 | #endif
|
106 | }
|
107 |
|
108 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
109 |
|
110 | void UOAudioPlay( UOAudioReplayProcT pProc, void *pData, int len )
|
111 | {
|
112 | #ifndef _Windows
|
113 | if ( audioReplayProc )
|
114 | return;
|
115 | audioReplayProc = pProc;
|
116 | audioCustomData = pData;
|
117 | audioSamplesToPlay = len*2;
|
118 | audioBufferSelect = 0;
|
119 | LATDCLR = BIT_2;
|
120 |
|
121 | audioCurBuffer = audioCurBufferEnd = 0;
|
122 |
|
123 | audioCustomDataPosition = 0;
|
124 |
|
125 | //fill buffer 1;
|
126 | CoreSetSoftwareInterrupt0();
|
127 | UOAudioStart();
|
128 | #endif
|
129 | }
|
130 |
|
131 |
|
132 | // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
133 | #ifndef _Windows
|
134 |
|
135 | void __ISR( _TIMER_4_VECTOR, ipl7) T4Interrupt( void)
|
136 | {
|
137 | LATDINV = BIT_2;
|
138 |
|
139 | if ( audioCurBuffer == audioCurBufferEnd )
|
140 | {
|
141 | audioBufferSelect ^= 1;
|
142 |
|
143 | if ( audioBufferSelect )
|
144 | {
|
145 | audioCurBuffer = audioBuffer1;
|
146 | audioCurBufferEnd = audioCurBuffer + audioBufferSize*2;
|
147 | }
|
148 | else
|
149 | {
|
150 | audioCurBuffer = audioBuffer2;
|
151 | audioCurBufferEnd = audioCurBuffer + audioBufferSize*2;
|
152 | }
|
153 | CoreSetSoftwareInterrupt0();
|
154 | }
|
155 |
|
156 | TMR2 = 0;
|
157 | SPI1BUF = *audioCurBuffer;
|
158 | ++audioCurBuffer;
|
159 |
|
160 |
|
161 | --audioSamplesToPlay;
|
162 | if ( audioSamplesToPlay == 0 )
|
163 | UOAudioStop();
|
164 |
|
165 | mT4ClearIntFlag();
|
166 | } // T4 Interrupt
|
167 |
|
168 |
|
169 | void __ISR(_CORE_SOFTWARE_0_VECTOR, ipl1) CoreSoftwareHandler0(void)
|
170 | {
|
171 | short *pBuffer;
|
172 | if ( audioReplayProc )
|
173 | {
|
174 | if ( !audioBufferSelect )
|
175 | pBuffer = audioBuffer1;
|
176 | else
|
177 | pBuffer = audioBuffer2;
|
178 |
|
179 | audioReplayProc( pBuffer, audioBufferSize, audioCustomData );
|
180 | }
|
181 |
|
182 | CoreClearSoftwareInterrupt0();
|
183 | INTClearFlag( INT_CS0 );
|
184 | }
|
185 | #endif
|