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