1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - demos.TWL - spi - mic-4
3 File: main.c
4
5 Copyright 2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2009-09-24#$
14 $Rev: 11063 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 /*---------------------------------------------------------------------------*
19 This sample controls microphone sampling, and outputs sampling data.
20
21 USAGE:
22 UP, DOWN: Control sampling span.
23 LEFT, RIGHT: Control sampling bit range. ( 8-bit, 12-bit, etc.)
24 A: Start / stop sampling (toggle)
25 B: Force-stop (Stop and ignore rest of data)
26 SELECT: Terminate program.
27
28 HOWTO:
29 1. Initialize MIC library and SNDEX library.
30 2. When sampling is stopped, you can change parameters
31 and start automatic microphone sampling.
32 Debug-output is sampling data for mic2wav.exe tool.
33 3. Debug-output log can make its waveform files with mic2wav.exe tool.
34 > $(TWLSDK_ROOT)/tools/bin/mic2wav.exe [logfile] [,directory]
35 Each set of sampling data (separated by A-Button) creates a waveform file
36 in '[directory]/%08X.wav'.
37
38 Note:
39 1. The speed of debug-output is later than sampling.
40 When you stop sampling, wait until all data is printed.
41 *---------------------------------------------------------------------------*/
42
43 #include <twl.h>
44 #include "DEMO.h"
45
46 /*---------------------------------------------------------------------------*
47 Constant definitions
48 *---------------------------------------------------------------------------*/
49 #define TEST_BUFFER_SIZE (1024 * 1024) // 1 MB
50 #define RETRY_MAX_COUNT 8
51
52 /*---------------------------------------------------------------------------*
53 Internal Function Definitions
54 *---------------------------------------------------------------------------*/
55 static void StartSampling(const MICAutoParam* param);
56 static void StopSampling(void);
57 static SNDEXFrequency GetI2SFrequency(void);
58 static void SetI2SFrequency(SNDEXFrequency freq);
59 static void SwitchI2SFrequency(void);
60
61 static void StepUpSamplingRate(void);
62 static void StepDownSamplingRate(void);
63 static void OnSamplingDone(MICResult result, void* arg);
64 static void OutputSampleWave(void* dat, MICSamplingType type);
65 static void StartSamplingOutput(void);
66 static void StopSamplingOutput(void);
67
68 static void SetDrawData(void *address, MICSamplingType type);
69 static void VBlankIntr(void);
70 static void Init3D(void);
71 static void Draw3D(void);
72 static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey);
73
74 /*---------------------------------------------------------------------------*
75 Internal Variable Definitions
76 *---------------------------------------------------------------------------*/
77 static MICAutoParam gMicAutoParam;
78 static u8 gDrawData[192];
79 static u8 gMicData[TEST_BUFFER_SIZE] ATTRIBUTE_ALIGN(HW_CACHE_LINE_SIZE);
80
81 static volatile BOOL g_sample_busy = FALSE;
82 static void* g_record_smps = NULL;
83
84 /*---------------------------------------------------------------------------*
85 Name: TwlMain
86
87 Description: Initialization and main loop.
88
89 Arguments: None.
90
91 Returns: None.
92 *---------------------------------------------------------------------------*/
TwlMain(void)93 void TwlMain(void)
94 {
95 /* Various types of initialization */
96 OS_Init();
97 FX_Init();
98 GX_Init();
99 GX_DispOff();
100 GXS_DispOff();
101
102 // When in NITRO mode, stopped by Panic
103 DEMOCheckRunOnTWL();
104
105 /* Initializes display settings */
106 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
107 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
108 (void)GX_DisableBankForLCDC();
109 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
110 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
111 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
112 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
113
114 /* 3D-related initialization */
115 Init3D();
116
117 /* Interrupt settings */
118 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
119 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
120 (void)OS_EnableIrq();
121 (void)OS_EnableInterrupts();
122 (void)GX_VBlankIntr(TRUE);
123
124 /* Initialize related libraries */
125 {
126 (void)PM_SetAmp(PM_AMP_ON);
127 SNDEX_Init();
128 MIC_Init();
129
130 gMicAutoParam.type = MIC_SAMPLING_TYPE_12BIT;
131 gMicAutoParam.buffer = (void *)gMicData;
132 gMicAutoParam.size = TEST_BUFFER_SIZE;
133 if ((OS_IsRunOnTwl() == TRUE) && (GetI2SFrequency() == SNDEX_FREQUENCY_47610))
134 {
135 gMicAutoParam.rate = MIC_SAMPLING_RATE_23810;
136 }
137 else
138 {
139 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360;
140 }
141 gMicAutoParam.loop_enable = FALSE;
142 gMicAutoParam.full_callback = OnSamplingDone;
143 }
144
145 /* Initialize internal variables */
146 MI_CpuFill8(gDrawData, 0x80, sizeof(gDrawData));
147
148 /* LCD display start */
149 GX_DispOn();
150 GXS_DispOn();
151
152 /* Debug string output */
153 OS_Printf("# mic-4 demo started.\n");
154 OS_Printf("# up/down -> change sampling rate\n");
155 OS_Printf("# left/right -> change bit range\n");
156 OS_Printf("# A -> start / stop\n");
157 OS_Printf("# B -> force-stop\n");
158 OS_Printf("# select -> terminate\n");
159
160 /* Empty call for getting key input data (strategy for pressing A Button in the IPL) */
161 (void)PAD_Read();
162
163 {
164 u16 keyOld = 0;
165 u16 keyTrg;
166 u16 keyNow;
167
168 /* Main loop */
169 while (TRUE)
170 {
171 /* Get key input data */
172 keyNow = PAD_Read();
173 keyTrg = (u16)((keyOld ^ keyNow) & keyNow);
174 keyOld = keyNow;
175
176 /* Start/stop sampling with the A Button */
177 if (keyTrg & PAD_BUTTON_A)
178 {
179 if (!g_sample_busy)
180 {
181 g_sample_busy = TRUE;
182 g_record_smps = gMicData;
183 StartSamplingOutput();
184 StartSampling(&gMicAutoParam);
185 }
186 else
187 {
188 StopSampling();
189 OnSamplingDone(MIC_RESULT_SUCCESS, NULL);
190 }
191 }
192 /* B Button stops sampling, ignores remaining data */
193 if (keyTrg & PAD_BUTTON_B)
194 {
195 if (g_sample_busy)
196 {
197 StopSampling();
198 OnSamplingDone(MIC_RESULT_SUCCESS, NULL);
199 }
200 if (g_record_smps)
201 {
202 StopSamplingOutput();
203 }
204 }
205 /* SELECT Button forcibly quits the program */
206 if (keyTrg & PAD_BUTTON_SELECT)
207 {
208 OS_Exit(0);
209 }
210 /* Change variable parameters */
211 if (!g_record_smps)
212 {
213 /* Change sampling type (bit width) */
214 if (keyTrg & (PAD_KEY_LEFT | PAD_KEY_RIGHT))
215 {
216 if (gMicAutoParam.type == MIC_SAMPLING_TYPE_8BIT)
217 {
218 gMicAutoParam.type = MIC_SAMPLING_TYPE_12BIT;
219 }
220 else
221 {
222 gMicAutoParam.type = MIC_SAMPLING_TYPE_8BIT;
223 }
224 StartSamplingOutput();
225 }
226 /* Change sampling rate */
227 if (keyTrg & PAD_KEY_UP)
228 {
229 StepUpSamplingRate();
230 StartSamplingOutput();
231 }
232 if (keyTrg & PAD_KEY_DOWN)
233 {
234 StepDownSamplingRate();
235 StartSamplingOutput();
236 }
237 }
238
239 /* Output a log of sampling results */
240 OutputSampleWave(MIC_GetLastSamplingAddress(), gMicAutoParam.type);
241
242 /* Render waveform */
243 if (g_sample_busy)
244 {
245 SetDrawData(MIC_GetLastSamplingAddress(), gMicAutoParam.type);
246 Draw3D();
247 }
248
249 /* Waiting for the V-Blank */
250 OS_WaitVBlankIntr();
251 }
252 }
253 }
254
255 /*---------------------------------------------------------------------------*
256 Name: StartSampling
257
258 Description: Calls the MIC_StartLimitedSampling function and performs error processing.
259
260 Arguments: param: Parameters passed to the microphone functions
261
262 Returns: None.
263 *---------------------------------------------------------------------------*/
264 static void
StartSampling(const MICAutoParam * param)265 StartSampling(const MICAutoParam* param)
266 {
267 MICResult result;
268 s32 retry = 0;
269
270 while (TRUE)
271 {
272 result = MIC_StartLimitedSampling(param);
273 switch (result)
274 {
275 case MIC_RESULT_SUCCESS: // Success
276 return;
277 case MIC_RESULT_BUSY: // Another thread is using the microphone
278 case MIC_RESULT_SEND_ERROR: // PXI queue is full
279 if (++ retry <= RETRY_MAX_COUNT)
280 {
281 OS_Sleep(1);
282 continue;
283 }
284 OS_TWarning("Retry count overflow.\n");
285 return;
286 case MIC_RESULT_ILLEGAL_STATUS: // Not in an autosampling stopped state
287 OS_TWarning("Already started sampling.\n");
288 return;
289 case MIC_RESULT_ILLEGAL_PARAMETER: // The specified parameter is not supported
290 OS_TWarning("Illegal parameter to start automatic sampling.\n");
291 return;
292 default: // Other fatal error
293 OS_Panic("Fatal error (%d).\n", result);
294 /* Never return */
295 }
296 }
297 }
298
299 /*---------------------------------------------------------------------------*
300 Name: StopSampling
301
302 Description: Calls the MIC_StopLimitedSampling function and performs error processing.
303
304 Arguments: None.
305
306 Returns: None.
307 *---------------------------------------------------------------------------*/
308 static void
StopSampling(void)309 StopSampling(void)
310 {
311 MICResult result;
312 s32 retry = 0;
313
314 while (TRUE)
315 {
316 result = MIC_StopLimitedSampling();
317 switch (result)
318 {
319 case MIC_RESULT_SUCCESS: // Success
320 case MIC_RESULT_ILLEGAL_STATUS: // Not in an autosampling state
321 return;
322 case MIC_RESULT_BUSY: // Microphone in use by other thread
323 case MIC_RESULT_SEND_ERROR: // PXI queue is full
324 if (++ retry <= RETRY_MAX_COUNT)
325 {
326 OS_Sleep(1);
327 continue;
328 }
329 OS_TWarning("Retry count overflow.\n");
330 return;
331 default: // Other fatal error
332 OS_Panic("Fatal error (%d).\n", result);
333 /* Never return */
334 }
335 }
336 }
337
338 #include <twl/ltdmain_begin.h>
339 /*---------------------------------------------------------------------------*
340 Name: GetI2SFrequency
341
342 Description: Gets the I2S operating frequency.
343
344 Arguments: None.
345
346 Returns: SNDEXFrequency: Returns the I2S operating frequency.
347 *---------------------------------------------------------------------------*/
348 static SNDEXFrequency
GetI2SFrequency(void)349 GetI2SFrequency(void)
350 {
351 SNDEXResult result;
352 SNDEXFrequency freq;
353 s32 retry = 0;
354
355 while (TRUE)
356 {
357 result = SNDEX_GetI2SFrequency(&freq);
358 switch (result)
359 {
360 case SNDEX_RESULT_SUCCESS: // Success
361 return freq;
362 case SNDEX_RESULT_EXCLUSIVE: // Exclusion error
363 case SNDEX_RESULT_PXI_SEND_ERROR: // PXI queue is full
364 if (++ retry <= RETRY_MAX_COUNT)
365 {
366 OS_Sleep(1);
367 continue;
368 }
369 OS_TWarning("Retry count overflow.\n");
370 break;
371 case SNDEX_RESULT_BEFORE_INIT: // Pre-initialization
372 case SNDEX_RESULT_ILLEGAL_STATE: // Abnormal state
373 OS_TWarning("Illegal state to get I2S frequency.\n");
374 break;
375 case SNDEX_RESULT_FATAL_ERROR: // Fatal error
376 default:
377 OS_Panic("Fatal error (%d).\n", result);
378 /* Never return */
379 }
380 }
381 return SNDEX_FREQUENCY_32730;
382 }
383
384 /*---------------------------------------------------------------------------*
385 Name: SetI2SFrequency
386
387 Description: Changes the I2S operating frequency.
388
389 Arguments: freq: I2S operating frequency.
390
391 Returns: None.
392 *---------------------------------------------------------------------------*/
393 static void
SetI2SFrequency(SNDEXFrequency freq)394 SetI2SFrequency(SNDEXFrequency freq)
395 {
396 SNDEXResult result;
397 s32 retry = 0;
398
399 while (TRUE)
400 {
401 result = SNDEX_SetI2SFrequency(freq);
402 switch (result)
403 {
404 case SNDEX_RESULT_SUCCESS: // Success
405 return;
406 case SNDEX_RESULT_EXCLUSIVE: // Exclusion error
407 case SNDEX_RESULT_PXI_SEND_ERROR: // PXI queue is full
408 if (++ retry <= RETRY_MAX_COUNT)
409 {
410 OS_Sleep(1);
411 continue;
412 }
413 OS_TWarning("Retry count overflow.\n");
414 return;
415 case SNDEX_RESULT_BEFORE_INIT: // Pre-initialization
416 case SNDEX_RESULT_ILLEGAL_STATE: // Abnormal state
417 OS_TWarning("Illegal state to set I2S frequency.\n");
418 return;
419 case SNDEX_RESULT_INVALID_PARAM: // Abnormal argument
420 OS_TWarning("Could not set I2S frequency into %d.\n", freq);
421 return;
422 case SNDEX_RESULT_FATAL_ERROR: // Fatal error
423 default:
424 OS_Panic("Fatal error (%d)\n", result);
425 /* Never return */
426 }
427 }
428 }
429
430 /*---------------------------------------------------------------------------*
431 Name: SwitchI2SFrequency
432
433 Description: Changes the I2S operating frequency in conjunction with the microphone sampling frequency.
434
435 Arguments: None.
436
437 Returns: None.
438 *---------------------------------------------------------------------------*/
439 static void
SwitchI2SFrequency(void)440 SwitchI2SFrequency(void)
441 {
442 SNDEXFrequency freq;
443
444 freq = GetI2SFrequency();
445 switch (gMicAutoParam.rate)
446 {
447 case MIC_SAMPLING_RATE_8180:
448 case MIC_SAMPLING_RATE_10910:
449 case MIC_SAMPLING_RATE_16360:
450 case MIC_SAMPLING_RATE_32730:
451 if (freq != SNDEX_FREQUENCY_32730)
452 {
453 SetI2SFrequency(SNDEX_FREQUENCY_32730);
454 }
455 break;
456 case MIC_SAMPLING_RATE_11900:
457 case MIC_SAMPLING_RATE_15870:
458 case MIC_SAMPLING_RATE_23810:
459 case MIC_SAMPLING_RATE_47610:
460 if (freq != SNDEX_FREQUENCY_47610)
461 {
462 SetI2SFrequency(SNDEX_FREQUENCY_47610);
463 }
464 break;
465 }
466 }
467
468 #include <twl/ltdmain_end.h>
469
470 /*---------------------------------------------------------------------------*
471 Name: StepUpSamplingRate
472
473 Description: Increases the microphone sampling frequency by one level.
474
475 Arguments: None.
476
477 Returns: None.
478 *---------------------------------------------------------------------------*/
479 static void
StepUpSamplingRate(void)480 StepUpSamplingRate(void)
481 {
482 if (OS_IsRunOnTwl() == TRUE)
483 {
484 switch (gMicAutoParam.rate)
485 {
486 case MIC_SAMPLING_RATE_8180: // 32.73k / 4
487 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910;
488 break;
489 case MIC_SAMPLING_RATE_10910: // 32.73k / 3
490 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900;
491 break;
492 case MIC_SAMPLING_RATE_11900: // 47.61k / 4
493 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870;
494 break;
495 case MIC_SAMPLING_RATE_15870: // 47.61k / 3
496 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360;
497 break;
498 case MIC_SAMPLING_RATE_16360: // 32.73k / 2
499 gMicAutoParam.rate = MIC_SAMPLING_RATE_23810;
500 break;
501 case MIC_SAMPLING_RATE_23810: // 47.61k / 2
502 gMicAutoParam.rate = MIC_SAMPLING_RATE_32730;
503 break;
504 case MIC_SAMPLING_RATE_32730: // 32.73k / 1
505 gMicAutoParam.rate = MIC_SAMPLING_RATE_47610;
506 break;
507 case MIC_SAMPLING_RATE_47610: // 47.61k / 1
508 default:
509 /* Do nothing */
510 return;
511 }
512 SwitchI2SFrequency();
513 }
514 else
515 {
516 switch (gMicAutoParam.rate)
517 {
518 case MIC_SAMPLING_RATE_8180: // 32.73k / 4
519 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910;
520 break;
521 case MIC_SAMPLING_RATE_10910: // 32.73k / 3
522 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900;
523 break;
524 case MIC_SAMPLING_RATE_11900: // 47.61k / 4
525 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870;
526 break;
527 case MIC_SAMPLING_RATE_15870: // 47.61k / 3
528 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360;
529 break;
530 case MIC_SAMPLING_RATE_16360: // 32.73k / 2
531 gMicAutoParam.rate = MIC_SAMPLING_RATE_23810;
532 break;
533 case MIC_SAMPLING_RATE_23810: // 47.61k / 2
534 default:
535 /* Do nothing */
536 return;
537 }
538 }
539 }
540
541 /*---------------------------------------------------------------------------*
542 Name: StepUpSamplingRate
543
544 Description: Decreases the microphone sampling frequency by one level.
545
546 Arguments: None.
547
548 Returns: None.
549 *---------------------------------------------------------------------------*/
550 static void
StepDownSamplingRate(void)551 StepDownSamplingRate(void)
552 {
553 if (OS_IsRunOnTwl() == TRUE)
554 {
555 switch (gMicAutoParam.rate)
556 {
557 case MIC_SAMPLING_RATE_47610: // 47.61k / 1
558 gMicAutoParam.rate = MIC_SAMPLING_RATE_32730;
559 break;
560 case MIC_SAMPLING_RATE_32730: // 32.73k / 1
561 gMicAutoParam.rate = MIC_SAMPLING_RATE_23810;
562 break;
563 case MIC_SAMPLING_RATE_23810: // 47.61k / 2
564 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360;
565 break;
566 case MIC_SAMPLING_RATE_16360: // 32.73k / 2
567 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870;
568 break;
569 case MIC_SAMPLING_RATE_15870: // 47.61k / 3
570 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900;
571 break;
572 case MIC_SAMPLING_RATE_11900: // 47.61k / 4
573 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910;
574 break;
575 case MIC_SAMPLING_RATE_10910: // 32.73k / 3
576 gMicAutoParam.rate = MIC_SAMPLING_RATE_8180;
577 break;
578 case MIC_SAMPLING_RATE_8180: // 32.73k / 4
579 default:
580 /* Do nothing */
581 return;
582 }
583 SwitchI2SFrequency();
584 }
585 else
586 {
587 switch (gMicAutoParam.rate)
588 {
589 case MIC_SAMPLING_RATE_23810: // 47.61k / 2
590 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360;
591 break;
592 case MIC_SAMPLING_RATE_16360: // 32.73k / 2
593 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870;
594 break;
595 case MIC_SAMPLING_RATE_15870: // 47.61k / 3
596 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900;
597 break;
598 case MIC_SAMPLING_RATE_11900: // 47.61k / 4
599 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910;
600 break;
601 case MIC_SAMPLING_RATE_10910: // 32.73k / 3
602 gMicAutoParam.rate = MIC_SAMPLING_RATE_8180;
603 break;
604 case MIC_SAMPLING_RATE_8180: // 32.73k / 4
605 default:
606 /* Do nothing */
607 return;
608 }
609 }
610 }
611
612 /*---------------------------------------------------------------------------*
613 Name: OnSamplingDone
614
615 Description: Updates the status flag when auto-sampling completes.
616
617 Arguments: result: Unused
618 arg: Unused
619
620 Returns: None.
621 *---------------------------------------------------------------------------*/
622 static void
OnSamplingDone(MICResult result,void * arg)623 OnSamplingDone(MICResult result, void* arg)
624 {
625 #pragma unused(result, arg)
626
627 if (g_sample_busy)
628 {
629 g_sample_busy = FALSE;
630 }
631 }
632
633 /*---------------------------------------------------------------------------*
634 Name: OutputSampleWave
635
636 Description: Debug output of sampling data.
637
638 Arguments: dat: Starting address of data to be output.
639 type: Microphone sampling type.
640
641 Returns: None.
642 *---------------------------------------------------------------------------*/
643 static void
OutputSampleWave(void * dat,MICSamplingType type)644 OutputSampleWave(void* dat, MICSamplingType type)
645 {
646 /* Up to 2 lines in a single cycle with 16-sample units.
647 If you output more than this amount, the log may contain omissions. */
648 enum { smps_per_line = 16, max_line_per_frame = 2 };
649 char buf[1 + (((MATH_MAX(sizeof(u8), sizeof(u16)) * 2) + 1) * smps_per_line) + 2];
650 char* s;
651 int lines, i, j;
652 u32 sample;
653 u8 temp;
654
655 if (!g_record_smps || !dat)
656 {
657 return;
658 }
659
660 DC_InvalidateRange((void*)g_record_smps, (u32)((u8*)dat - (u8*)g_record_smps));
661 switch (type)
662 {
663 case MIC_SAMPLING_TYPE_8BIT:
664 /* In the case of 8-bit sampling */
665 for (lines = 0; (lines < max_line_per_frame) && ((u8*)g_record_smps + smps_per_line <= (u8*)dat); lines ++)
666 {
667 s = buf;
668 *s ++ = '|';
669 for (i = 0; i < smps_per_line; i ++)
670 {
671 sample = (u32)(((u8*)g_record_smps)[i]);
672 for (j = 0; j < (sizeof(u8) * 2); j ++)
673 {
674 temp = (u8)((sample >> (((sizeof(u8) * 2) - 1 - j) * 4)) & 0x0f);
675 *s ++ = (char)((temp < 10) ? ('0' + temp) : ('A' + temp - 10));
676 }
677 *s ++ = ',';
678 }
679 *s ++ = '\n';
680 *s = '\0';
681 OS_FPutString(OS_PRINT_OUTPUT_CURRENT, buf);
682 g_record_smps = (void*)((u8*)g_record_smps + smps_per_line);
683 }
684 break;
685 case MIC_SAMPLING_TYPE_12BIT:
686 /* In the case of 12-bit sampling */
687 for (lines = 0; (lines < max_line_per_frame) && ((u16*)g_record_smps + smps_per_line <= (u16*)dat); lines ++)
688 {
689 s = buf;
690 *s ++ = '|';
691 for (i = 0; i < smps_per_line; i ++)
692 {
693 sample = (u32)(((u16*)g_record_smps)[i]);
694 for (j = 0; j < (sizeof(u16) * 2); j ++)
695 {
696 temp = (u8)((sample >> (((sizeof(u16) * 2) - 1 - j) * 4)) & 0x0f);
697 *s ++ = (char)((temp < 10) ? ('0' + temp) : ('A' + temp - 10));
698 }
699 *s ++ = ',';
700 }
701 *s ++ = '\n';
702 *s = '\0';
703 OS_FPutString(OS_PRINT_OUTPUT_CURRENT, buf);
704 g_record_smps = (void*)((u16*)g_record_smps + smps_per_line);
705 }
706 break;
707 }
708
709 if (!g_sample_busy && g_record_smps)
710 {
711 if (((u8*)g_record_smps + (smps_per_line * max_line_per_frame)) >= (u8*)dat)
712 {
713 StopSamplingOutput();
714 }
715 }
716 }
717
718 /*---------------------------------------------------------------------------*
719 Name: StartSamplingOutput
720
721 Description: Debug output of string indicating start of sampling output.
722
723 Arguments: None.
724
725 Returns: None.
726 *---------------------------------------------------------------------------*/
727 static void
StartSamplingOutput(void)728 StartSamplingOutput(void)
729 {
730 s32 range = 0;
731 s32 rate = 0;
732
733 switch (gMicAutoParam.type)
734 {
735 case MIC_SAMPLING_TYPE_8BIT: range = 8; break;
736 case MIC_SAMPLING_TYPE_12BIT: range = 16; break;
737 }
738
739 switch (gMicAutoParam.rate)
740 {
741 case MIC_SAMPLING_RATE_32730: rate = 32730; break;
742 case MIC_SAMPLING_RATE_16360: rate = 16360; break;
743 case MIC_SAMPLING_RATE_10910: rate = 10910; break;
744 case MIC_SAMPLING_RATE_8180: rate = 8180; break;
745 case MIC_SAMPLING_RATE_47610: rate = 47610; break;
746 case MIC_SAMPLING_RATE_23810: rate = 23810; break;
747 case MIC_SAMPLING_RATE_15870: rate = 15870; break;
748 case MIC_SAMPLING_RATE_11900: rate = 11900; break;
749 }
750
751 OS_Printf("$rate=%d\n$bits=%d\n", rate, range);
752 }
753
754 /*---------------------------------------------------------------------------*
755 Name: StopSamplingOutput
756
757 Description: Debug output of string indicating end of sampling output.
758
759 Arguments: None.
760
761 Returns: None.
762 *---------------------------------------------------------------------------*/
763 static void
StopSamplingOutput(void)764 StopSamplingOutput(void)
765 {
766 OS_Printf("$end\n\n");
767 g_record_smps = NULL;
768 }
769
770 /*---------------------------------------------------------------------------*
771 Name: SetDrawData
772
773 Description: Stores the current newest sampled data in the buffer that puts it on the display.
774
775
776 Arguments: address: Location in main memory where the most recent sampling data was stored by the component
777
778 type: Sampling type (bit width)
779
780 Returns: None.
781 *---------------------------------------------------------------------------*/
SetDrawData(void * address,MICSamplingType type)782 static void SetDrawData(void *address, MICSamplingType type)
783 {
784 s32 i;
785
786 /* If sampling has never been performed, do nothing and stop.
787 (Because it would delete memory cache(s) unrelated to the microphone) */
788 if ((address < gMicData) || (address >= (gMicData + TEST_BUFFER_SIZE)))
789 {
790 return;
791 }
792
793 switch (type)
794 {
795 case MIC_SAMPLING_TYPE_8BIT:
796 /* In the case of 8-bit sampling */
797 {
798 u8 *p;
799
800 p = (u8 *)((u32)address - 191);
801 if (p < gMicData)
802 {
803 p = (u8 *)((u32)p + TEST_BUFFER_SIZE);
804 }
805 DC_InvalidateRange((void *)((u32)p & ~(HW_CACHE_LINE_SIZE - 1)), HW_CACHE_LINE_SIZE);
806 for (i = 0; i < 192; i++)
807 {
808 gDrawData[i] = *p;
809 p++;
810 if ((u32)p >= (u32)(gMicData + TEST_BUFFER_SIZE))
811 {
812 p -= TEST_BUFFER_SIZE;
813 }
814 if (((u32)p % HW_CACHE_LINE_SIZE) == 0)
815 {
816 DC_InvalidateRange(p, HW_CACHE_LINE_SIZE);
817 }
818 }
819 }
820 break;
821 case MIC_SAMPLING_TYPE_12BIT:
822 /* For 12-bit sampling */
823 {
824 u16 *p;
825
826 p = (u16 *)((u32)address - 382);
827 if ((u32)p < (u32)gMicData)
828 {
829 p = (u16 *)((u32)p + TEST_BUFFER_SIZE);
830 }
831 DC_InvalidateRange((void *)((u32)p & ~(HW_CACHE_LINE_SIZE - 1)), HW_CACHE_LINE_SIZE);
832 for (i = 0; i < 192; i++)
833 {
834 gDrawData[i] = (u8)((*p >> 8) & 0x00ff);
835 p++;
836 if ((u32)p >= (u32)(gMicData + TEST_BUFFER_SIZE))
837 {
838 p = (u16 *)((u32)p - TEST_BUFFER_SIZE);
839 }
840 if (((u32)p % HW_CACHE_LINE_SIZE) == 0)
841 {
842 DC_InvalidateRange(p, HW_CACHE_LINE_SIZE);
843 }
844 }
845 }
846 break;
847 }
848 }
849
850 /*---------------------------------------------------------------------------*
851 Name: VBlankIntr
852
853 Description: V-Blank interrupt vector.
854
855 Arguments: None.
856
857 Returns: None.
858 *---------------------------------------------------------------------------*/
VBlankIntr(void)859 static void VBlankIntr(void)
860 {
861 /* Sets the IRQ check flag */
862 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
863 }
864
865 /*---------------------------------------------------------------------------*
866 Name: Init3D
867
868 Description: Initialization for 3D display
869
870 Arguments: None.
871
872 Returns: None.
873 *---------------------------------------------------------------------------*/
Init3D(void)874 static void Init3D(void)
875 {
876 G3X_Init();
877 G3X_InitMtxStack();
878 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_3D);
879 GX_SetVisiblePlane(GX_PLANEMASK_BG0);
880 G2_SetBG0Priority(0);
881 G3X_AlphaTest(FALSE, 0);
882 G3X_AntiAlias(TRUE);
883 G3X_EdgeMarking(FALSE);
884 G3X_SetFog(FALSE, (GXFogBlend)0, (GXFogSlope)0, 0);
885 G3X_SetClearColor(0, 0, 0x7fff, 63, FALSE);
886 G3_ViewPort(0, 0, 255, 191);
887 G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
888 }
889
890 /*---------------------------------------------------------------------------*
891 Name: Draw3D
892
893 Description: Displays waveforms in 3D.
894
895 Arguments: None.
896
897 Returns: None.
898 *---------------------------------------------------------------------------*/
Draw3D(void)899 static void Draw3D(void)
900 {
901 G3X_Reset();
902 G3_Identity();
903 G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, 0, 31, 0);
904
905 {
906 s32 i;
907
908 if ((gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_8BIT) ||
909 (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT) ||
910 (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF))
911 {
912 for (i = 0; i < 191; i++)
913 {
914 DrawLine((s16)((s8)gDrawData[i]),
915 (s16)i, (s16)((s8)gDrawData[i + 1]), (s16)(i + 1));
916 }
917 }
918 else
919 {
920 for (i = 0; i < 191; i++)
921 {
922 DrawLine((s16)(gDrawData[i]), (s16)i, (s16)(gDrawData[i + 1]), (s16)(i + 1));
923 }
924 }
925 }
926
927 G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
928 }
929
930 /*---------------------------------------------------------------------------*
931 Name: DrawLine
932
933 Description: Renders lines with triangular polygons
934
935 Arguments: sx: x coordinate of line's starting point
936 sy: y coordinate of line's starting point
937 ex: x coordinate of line's ending point
938 ey: y coordinate of line's ending point
939
940 Returns: None.
941 *---------------------------------------------------------------------------*/
DrawLine(s16 sx,s16 sy,s16 ex,s16 ey)942 static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey)
943 {
944 fx16 fsx = (fx16)(((sx - 128) * 0x1000) / 128);
945 fx16 fsy = (fx16)(((96 - sy) * 0x1000) / 96);
946 fx16 fex = (fx16)(((ex - 128) * 0x1000) / 128);
947 fx16 fey = (fx16)(((96 - ey) * 0x1000) / 96);
948
949 G3_Begin(GX_BEGIN_TRIANGLES);
950 {
951 G3_Color(GX_RGB(31, 31, 31));
952 G3_Vtx(fsx, fsy, 0);
953 G3_Color(GX_RGB(31, 31, 31));
954 G3_Vtx(fex, fey, 0);
955 G3_Color(GX_RGB(31, 31, 31));
956 G3_Vtx(fsx, fsy, 1);
957 }
958 G3_End();
959 }
960
961 /*---------------------------------------------------------------------------*
962 End of file
963 *---------------------------------------------------------------------------*/
964