1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - SND - demos - channel
3 File: main.c
4
5 Copyright 2007-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:: 2008-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17 #ifdef SDK_TWL
18 #include <twl.h>
19 #else
20 #include <nitro.h>
21 #endif
22
23 #include "organ_det.g3.pcm16.h"
24 #include "wihaho.pcm16.h"
25
26 // Macro to calculate PSG frequency
27 #define FreqToTimer(freq) (SND_TIMER_CLOCK / ( 8 * (freq) ))
28 #define KeyToTimer(key) (SND_CalcTimer(FreqToTimer(440), ((key)-69)*64))
29
30 #define PCM_PLAY_CHANNEL1 4
31 #define PCM_PLAY_CHANNEL2 5
32 #define PSG_PLAY_CHANNEL 8
33 #define NOISE_PLAY_CHANNEL 14
34
35 #define CENTER_PAN 64
36
37 u16 Cont;
38 u16 Trg;
39 u8 key = 60;
40
41 void VBlankIntr(void);
42
43 /*---------------------------------------------------------------------------*
44 Name: NitroMain
45
46 Description: Main.
47
48 Arguments: None.
49
50 Returns: None.
51 *---------------------------------------------------------------------------*/
NitroMain()52 void NitroMain()
53 {
54 // Initialization
55 OS_Init();
56 GX_Init();
57 SND_Init();
58
59 // V-Blank interrupt settings
60 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
61 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
62 (void)OS_EnableIrq();
63 (void)GX_VBlankIntr(TRUE);
64
65 // Print usage
66 OS_Printf("=================================\n");
67 OS_Printf("USAGE:\n");
68 OS_Printf(" A, B, X, Y : start sound\n");
69 OS_Printf(" START : stop sound\n");
70 OS_Printf("=================================\n");
71
72 // Lock the channel
73 SND_LockChannel((1 << PCM_PLAY_CHANNEL1) | (1 << PCM_PLAY_CHANNEL2) | (1 << PSG_PLAY_CHANNEL) |
74 (1 << NOISE_PLAY_CHANNEL), 0);
75
76 while (1)
77 {
78 u16 ReadData;
79
80 OS_WaitVBlankIntr();
81
82 // Receive ARM7 command reply
83 while (SND_RecvCommandReply(SND_COMMAND_NOBLOCK) != NULL)
84 {
85 }
86
87 ReadData = PAD_Read();
88 Trg = (u16)(ReadData & (ReadData ^ Cont));
89 Cont = ReadData;
90
91 // Play PCM
92 if (Trg & PAD_BUTTON_A)
93 {
94 SND_SetupChannelPcm(PCM_PLAY_CHANNEL1,
95 ORGAN_DET_G3_PCM16_FORMAT,
96 organ_det_g3_pcm16,
97 ORGAN_DET_G3_PCM16_LOOPFLAG ? SND_CHANNEL_LOOP_REPEAT :
98 SND_CHANNEL_LOOP_1SHOT, ORGAN_DET_G3_PCM16_LOOPSTART,
99 ORGAN_DET_G3_PCM16_LOOPLEN, 127, SND_CHANNEL_DATASHIFT_NONE,
100 SND_CalcTimer(ORGAN_DET_G3_PCM16_TIMER, ((key) - 67) * 64),
101 CENTER_PAN);
102 SND_StartTimer(1 << PCM_PLAY_CHANNEL1, 0, 0, 0);
103 }
104
105 if (Trg & PAD_BUTTON_B)
106 {
107 SND_SetupChannelPcm(PCM_PLAY_CHANNEL2,
108 WIHAHO_PCM16_FORMAT,
109 wihaho_pcm16,
110 WIHAHO_PCM16_LOOPFLAG ? SND_CHANNEL_LOOP_REPEAT :
111 SND_CHANNEL_LOOP_1SHOT, WIHAHO_PCM16_LOOPSTART,
112 WIHAHO_PCM16_LOOPLEN, 127, SND_CHANNEL_DATASHIFT_NONE,
113 WIHAHO_PCM16_TIMER, CENTER_PAN);
114 SND_StartTimer(1 << PCM_PLAY_CHANNEL2, 0, 0, 0);
115 }
116
117 // Plays the PSG square wave
118 if (Trg & PAD_BUTTON_X)
119 {
120 SND_SetupChannelPsg(PSG_PLAY_CHANNEL,
121 SND_DUTY_4_8,
122 64, SND_CHANNEL_DATASHIFT_NONE, KeyToTimer(key), CENTER_PAN);
123 SND_StartTimer(1 << PSG_PLAY_CHANNEL, 0, 0, 0);
124 }
125
126 // Plays noise
127 if (Trg & PAD_BUTTON_Y)
128 {
129 SND_SetupChannelNoise(NOISE_PLAY_CHANNEL,
130 64, SND_CHANNEL_DATASHIFT_NONE, KeyToTimer(key), CENTER_PAN);
131 SND_StartTimer(1 << NOISE_PLAY_CHANNEL, 0, 0, 0);
132 }
133
134 // Stop
135 if (Trg & PAD_BUTTON_START)
136 {
137 SND_StopTimer((1 << PCM_PLAY_CHANNEL1) | (1 << PCM_PLAY_CHANNEL2) |
138 (1 << PSG_PLAY_CHANNEL) | (1 << NOISE_PLAY_CHANNEL), 0, 0, 0);
139 }
140
141 // Raises the playback a half-step
142 if (Trg & PAD_KEY_UP)
143 {
144 key++;
145 SND_SetChannelTimer(1 << PCM_PLAY_CHANNEL1,
146 SND_CalcTimer(ORGAN_DET_G3_PCM16_TIMER, ((key) - 67) * 64));
147 SND_SetChannelTimer((1 << PSG_PLAY_CHANNEL) | (1 << NOISE_PLAY_CHANNEL),
148 KeyToTimer(key));
149 OS_Printf("key: %d\n", key);
150 }
151
152 // Lowers the playback a half-step
153 if (Trg & PAD_KEY_DOWN)
154 {
155 key--;
156 SND_SetChannelTimer(1 << PCM_PLAY_CHANNEL1,
157 SND_CalcTimer(ORGAN_DET_G3_PCM16_TIMER, ((key) - 67) * 64));
158 SND_SetChannelTimer((1 << PSG_PLAY_CHANNEL) | (1 << NOISE_PLAY_CHANNEL),
159 KeyToTimer(key));
160 OS_Printf("key: %d\n", key);
161 }
162
163 // Command flush
164 (void)SND_FlushCommand(SND_COMMAND_NOBLOCK);
165 }
166 }
167
168 //--------------------------------------------------------------------------------
169 // V-Blank interrupt process
170 //
VBlankIntr(void)171 void VBlankIntr(void)
172 {
173 OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Checking V-Blank interrupt
174 }
175