1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - SND - demos - seq
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-10-02#$
14 $Rev: 8827 $
15 $Author: yosizaki $
16 *---------------------------------------------------------------------------*/
17
18 //---------------------------------------------------------------------------
19 // USAGE:
20 // A: Start sequence
21 // B: Stop sequence
22 //---------------------------------------------------------------------------
23
24 #ifdef SDK_TWL
25 #include <twl.h>
26 #else
27 #include <nitro.h>
28 #endif
29
30 #include "seq.h"
31 #include "channel.h"
32
33 #define MIDI_BUF_SIZE 8*1024
34 #define CHANNEL_NUM 4
35 #define ORIGINAL_KEY 67
36
37 u16 Cont;
38 u16 Trg;
39
40 u8 midifile_buf[MIDI_BUF_SIZE];
41
42 static SeqHandle handle;
43
44 void VBlankIntr(void);
45 void FileLoad(void *buf, const char *filename);
46 void MidiCallback(const u8 *midi_event);
47
48
49 /*---------------------------------------------------------------------------*
50 Name: NitroMain
51
52 Description: Main function.
53
54 Arguments: None.
55
56 Returns: None.
57 *---------------------------------------------------------------------------*/
NitroMain()58 void NitroMain()
59 {
60 // Initialization
61 OS_Init();
62 GX_Init();
63 (void)OS_EnableIrq();
64 (void)OS_EnableInterrupts();
65 FS_Init(FS_DMA_NOT_USE);
66 SND_Init();
67
68 SeqInit(SEQ_CLOCK_INTERVAL_NITRO_VBLANK, MidiCallback);
69 ChInit();
70
71 // V-Blank interrupt settings
72 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
73 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
74 (void)OS_EnableIrq();
75 (void)GX_VBlankIntr(TRUE);
76
77 // Print usage
78 OS_Printf("=================================\n");
79 OS_Printf("USAGE:\n");
80 OS_Printf(" A : start sequence\n");
81 OS_Printf(" B : stop sequence\n");
82 OS_Printf("=================================\n");
83
84 // Load a MIDI file
85 FileLoad(midifile_buf, "/elise.mid");
86
87 while (1)
88 {
89 u16 ReadData;
90
91 OS_WaitVBlankIntr();
92
93 // Receive ARM7 command reply
94 while (SND_RecvCommandReply(SND_COMMAND_NOBLOCK) != NULL)
95 {
96 }
97
98 // Read key input
99 ReadData = PAD_Read();
100 Trg = (u16)(ReadData & (ReadData ^ Cont));
101 Cont = ReadData;
102
103 if (Trg & PAD_BUTTON_A)
104 {
105 ChAllNoteOff();
106 (void)SeqPlay(&handle, midifile_buf);
107 }
108
109 if (Trg & PAD_BUTTON_B)
110 {
111 (void)SeqStop(&handle);
112 ChAllNoteOff();
113 }
114
115 (void)SeqMain(&handle);
116
117 // Command Flash (requests immediate execution of flash)
118 (void)SND_FlushCommand(SND_COMMAND_NOBLOCK | SND_COMMAND_IMMEDIATE);
119 }
120 }
121
VBlankIntr(void)122 void VBlankIntr(void)
123 {
124 OS_SetIrqCheckFlag(OS_IE_V_BLANK); // Checking V-Blank interrupt
125 }
126
FileLoad(void * buf,const char * filename)127 void FileLoad(void *buf, const char *filename)
128 {
129 FSFile file;
130 u32 file_size;
131
132 FS_InitFile(&file);
133 (void)FS_OpenFileEx(&file, filename, FS_FILEMODE_R);
134 file_size = FS_GetFileLength(&file);
135 (void)FS_ReadFile(&file, buf, (s32)file_size);
136 (void)FS_CloseFile(&file);
137 }
138
139 /*---------------------------------------------------------------------------*
140 Name: MidiCallback
141
142 Description: Function called when a MIDI event occurs during the SeqMain sequence.
143
144
145 Arguments: midi_event: Array of occurred MIDI events
146
147 Returns: None.
148 *---------------------------------------------------------------------------*/
MidiCallback(const u8 * midi_event)149 void MidiCallback(const u8 *midi_event)
150 {
151 static u8 running_status;
152 u8 midi_buf[4];
153 int i;
154
155 // Byte size by MIDI event
156 const u8 midi_byte_size[8] = {
157 /* 8x,9x,Ax,Bx,Cx,Dx,Ex,Fx */
158 2, 2, 2, 2, 1, 1, 2, 0
159 };
160
161 // Check the running status
162 if (midi_event[0] < 0x80)
163 {
164 midi_buf[0] = running_status;
165 for (i = 0; i < midi_byte_size[(midi_buf[0] >> 4) - 8]; i++)
166 {
167 midi_buf[i + 1] = midi_event[i];
168 }
169 }
170 else
171 {
172 running_status = midi_event[0];
173 midi_buf[0] = midi_event[0];
174 for (i = 0; i < midi_byte_size[(midi_buf[0] >> 4) - 8]; i++)
175 {
176 midi_buf[i + 1] = midi_event[i + 1];
177 }
178 }
179
180 ChSetEvent(midi_buf);
181 }
182