1
+ /*
2
+ * Based on mBed's repo, algorithm based of the wave_player library by Steve Ravet
3
+ * https://os.mbed.com/users/sparkfun/code/wave_player/
4
+ * Adapted to GIGA R1
5
+ */
6
+
7
+ #include " wav_seeker.h"
8
+
9
+ unsigned short DAC_fifo[256 ];
10
+ short DAC_wptr;
11
+ volatile short DAC_rptr;
12
+ short DAC_on;
13
+
14
+ typedef struct uFMT_STRUCT {
15
+ short comp_code;
16
+ short num_channels;
17
+ unsigned sample_rate;
18
+ unsigned avg_Bps;
19
+ short block_align;
20
+ short sig_bps;
21
+ } FMT_STRUCT;
22
+
23
+ void wav_play_rl (FILE *wavefile, AdvancedDAC &dac_out, bool verbosity){
24
+ unsigned chunk_id,chunk_size,channel;
25
+ unsigned data,samp_int,i;
26
+ short unsigned dac_data;
27
+ long long slice_value;
28
+ char *slice_buf;
29
+ short *data_sptr;
30
+ unsigned char *data_bptr;
31
+ int *data_wptr;
32
+ FMT_STRUCT wav_format;
33
+ long slice,num_slices;
34
+ DAC_wptr=0 ;
35
+ DAC_rptr=0 ;
36
+
37
+ for (i=0 ;i<256 ;i+=2 ) {
38
+ DAC_fifo[i]=0 ;
39
+ DAC_fifo[i+1 ]=3000 ;
40
+ }
41
+
42
+ DAC_wptr=4 ;
43
+ DAC_on=0 ;
44
+
45
+ fread (&chunk_id,4 ,1 ,wavefile);
46
+ fread (&chunk_size,4 ,1 ,wavefile);
47
+
48
+ while (!feof (wavefile)) {
49
+ if (verbosity)
50
+ Serial.print (F (" Read chunk ID =" ));
51
+ Serial.println (chunk_id);
52
+ Serial.print (F (" Read chunk size =" ));
53
+ Serial.println (chunk_size);
54
+
55
+ switch (chunk_id) {
56
+ case 0x46464952 :
57
+ fread (&data,4 ,1 ,wavefile);
58
+ if (verbosity) {
59
+ Serial.println (F (" RIFF chunk" ));
60
+ Serial.print (F (" chunk size = " ));
61
+ Serial.println (chunk_size);
62
+ Serial.print (F (" RIFF type = " ));
63
+ Serial.println (data);
64
+ }
65
+ break ;
66
+ case 0x20746d66 :
67
+ fread (&wav_format,sizeof (wav_format),1 ,wavefile);
68
+ if (verbosity) {
69
+ Serial.println (F (" FORMAT chunk" ));
70
+ Serial.print (F (" chunk size = " ));
71
+ Serial.println (chunk_size);
72
+ Serial.print (F (" compression code =" ));
73
+ Serial.println (wav_format.comp_code );
74
+ Serial.print (F (" channels =" ));
75
+ Serial.println (wav_format.num_channels );
76
+ Serial.print (F (" samples/sec =" ));
77
+ Serial.println (wav_format.sample_rate );
78
+ Serial.print (F (" bytes/sec =" ));
79
+ Serial.println (wav_format.avg_Bps );
80
+ Serial.print (F (" block align =" ));
81
+ Serial.println (wav_format.block_align );
82
+ Serial.print (F (" bits per sample =" ));
83
+ Serial.println (wav_format.sig_bps );
84
+ }
85
+
86
+ // Initializing AdvancedAnalogRedux
87
+
88
+ if (!dac_out.begin (AN_RESOLUTION_12, wav_format.sample_rate , 256 , 512 )) {
89
+ Serial.println (" Failed to start DAC1 !" );
90
+ while (1 );
91
+ } else {
92
+ Serial.println (F (" DAC1 Initialized" ));
93
+ }
94
+
95
+ if (chunk_size > sizeof (wav_format))
96
+ fseek (wavefile,chunk_size-sizeof (wav_format),SEEK_CUR);
97
+ break ;
98
+ case 0x61746164 :
99
+ slice_buf=(char *)malloc (wav_format.block_align );
100
+ if (!slice_buf) {
101
+ Serial.println (F (" Unable to malloc slice buffer" ));
102
+ exit (1 );
103
+ }
104
+ num_slices=chunk_size/wav_format.block_align ;
105
+ samp_int=1000000 /(wav_format.sample_rate );
106
+
107
+ if (verbosity) {
108
+ Serial.println (F (" DATA chunk" ));
109
+ Serial.print (F (" chunk size =" ));
110
+ Serial.println (chunk_size);
111
+ Serial.print (F (" slices =" ));
112
+ Serial.println (num_slices);
113
+ Serial.print (F (" Ideal sample interval= " ));
114
+ Serial.println ((unsigned )(1000000.0 /wav_format.sample_rate ));
115
+ Serial.print (F (" programmed interrupt tick interval =" ));
116
+ Serial.println (samp_int);
117
+ }
118
+ DAC_on=1 ;
119
+
120
+ for (slice=0 ;slice<num_slices;slice+=1 ) {
121
+ while (dac_out.available ()) {
122
+ fread (slice_buf,wav_format.block_align ,1 ,wavefile);
123
+ if (feof (wavefile)) {
124
+ Serial.println (F (" Oops -- not enough slices in the wave file\n " ));
125
+ exit (1 );
126
+ }
127
+ data_sptr=(short *)slice_buf; // 16 bit samples
128
+ data_bptr=(unsigned char *)slice_buf; // 8 bit samples
129
+ data_wptr=(int *)slice_buf; // 32 bit samples
130
+ slice_value=0 ;
131
+ for (channel=0 ;channel<wav_format.num_channels ;channel++) {
132
+ switch (wav_format.sig_bps ) {
133
+ case 16 :
134
+ if (verbosity)
135
+ Serial.print (F (" 16 bit channel =" ));
136
+ Serial.println (channel);
137
+ Serial.print (F (" data = " ));
138
+ Serial.println (data_sptr[channel]);
139
+ slice_value+=data_sptr[channel];
140
+ break ;
141
+ case 32 :
142
+ if (verbosity)
143
+ Serial.print (F (" 32 bit channel =" ));
144
+ Serial.println (channel);
145
+ Serial.print (F (" data = " ));
146
+ Serial.println (data_wptr[channel]);
147
+ slice_value+=data_wptr[channel];
148
+ break ;
149
+ case 8 :
150
+ if (verbosity)
151
+ Serial.print (F (" 8 bit channel =" ));
152
+ Serial.println (channel);
153
+ Serial.print (F (" data = " ));
154
+ Serial.println ((int )data_bptr[channel]);
155
+ slice_value+=data_bptr[channel];
156
+ break ;
157
+ }
158
+ }
159
+ slice_value/=wav_format.num_channels ;
160
+
161
+ switch (wav_format.sig_bps ) {
162
+ // Working for 8 bit for 12 bit output - acceleartes in the end
163
+ case 8 : slice_value<<=4 ;
164
+ break ;
165
+ // WORKING 12 BIT - SCALING DOWN FROM 16 BIT TO 12 BIT (Applied from 16-Bit wav sample files )
166
+ case 16 : slice_value = (((slice_value+32768 )>>4 ) & 0xfff );
167
+ break ;
168
+ // 32-Bit Case - Won't be used with GIGA as the highest resolution will be 12-Bit
169
+ case 32 : slice_value>>=16 ;
170
+ slice_value+=32768 ;
171
+ break ;
172
+ }
173
+ dac_data=(short unsigned )slice_value;
174
+ if (verbosity)
175
+ Serial.print (F (" DAC-Data >>>>>>>>>>>>>>" ));
176
+ Serial.print (F (" sample =" ));
177
+ Serial.println (slice);
178
+ Serial.print (F (" wptr =" ));
179
+ Serial.println (DAC_wptr);
180
+ Serial.print (F (" slice value =" ));
181
+ Serial.println ((int )slice_value);
182
+ Serial.print (F (" dac_data =" ));
183
+ Serial.println (dac_data);
184
+ DAC_fifo[DAC_wptr]=dac_data;
185
+
186
+ // Custom_mode begin
187
+
188
+ DAC_wptr=(DAC_wptr+1 ) & 0xff ;
189
+ // Conditional addition to switch between channels - FOR STEREO
190
+ if (DAC_wptr >= 255 ){
191
+ static size_t lut_offs = 0 ;
192
+
193
+ Serial.println (F (" Proceeding DAC ..." ));
194
+ // Get a free buffer for writing.
195
+ SampleBuffer buf = dac_out.dequeue ();
196
+ // Write data to buffer.
197
+ for (size_t i=0 ; i<buf.size (); i++, lut_offs++) {
198
+ buf[i] = DAC_fifo[lut_offs % (sizeof (DAC_fifo)/sizeof (DAC_fifo[0 ]))];
199
+ }
200
+
201
+ // Writethe buffer to DAC.
202
+ Serial.println (F (" Writing to DAC ..." ));
203
+ dac_out.write (buf);
204
+
205
+ DAC_wptr = 0 ;
206
+ } else {
207
+ Serial.println (F (" Slicing" ));
208
+ }
209
+ // Custom_mode end
210
+ }
211
+ }
212
+ DAC_on=0 ;
213
+ free (slice_buf);
214
+ break ;
215
+ case 0x5453494c :
216
+ if (verbosity)
217
+ Serial.print (F (" INFO chunk, size" ));
218
+ Serial.println (chunk_size);
219
+ fseek (wavefile,chunk_size,SEEK_CUR);
220
+ break ;
221
+ default :
222
+ Serial.print (F (" unknown chunk type =" ));
223
+ Serial.println (chunk_id);
224
+ Serial.print (F (" chunk size =" ));
225
+ Serial.println (chunk_size);
226
+ data=fseek (wavefile,chunk_size,SEEK_CUR);
227
+ break ;
228
+ }
229
+ fread (&chunk_id,4 ,1 ,wavefile);
230
+ fread (&chunk_size,4 ,1 ,wavefile);
231
+ }
232
+ Serial.println (F (" Finished reading file" ));
233
+ }
0 commit comments