1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: main.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: $
16 *---------------------------------------------------------------------------*/
17
18 #include "precompiled.h"
19
20 #include <nw/snd.h>
21 #include "demolib.h"
22 #include "simple.csid"
23
24
25 /*---------------------------------------------------------------------------*
26
27 *---------------------------------------------------------------------------*/
28 namespace
29 {
30
31 const s32 SOUND_THREAD_PRIORITY = 4;
32 const s32 LOAD_THREAD_PRIORITY = 3;
33 const s32 SOUND_HEAP_SIZE = 1 * 1024 * 1024;
34 const char SOUND_ARC_PATH[] = NW_SND_DEMO_PATH_PREFIX "simple.bcsar";
35 const char DEMO_TITLE[] = "Filter";
36
37 const f32 BIQUAD_FILTER_VALUE_MIN = 0.0f;
38 const f32 BIQUAD_FILTER_VALUE_MAX = 1.0f;
39 const f32 BIQUAD_FILTER_VALUE_DELTA = 0.05f;
40 const f32 LPF_VALUE_MIN = -1.0f;
41 const f32 LPF_VALUE_MAX = 0.0f;
42 const f32 LPF_VALUE_DELTA = 0.05f;
43
44 enum FilterType
45 {
46 FILTER_TYPE_NONE,
47 FILTER_TYPE_LPF, // �P�Ƀt�B���^
48 FILTER_TYPE_BIQUAD_LPF, // �ȉ��A�o�Ƀt�B���^
49 FILTER_TYPE_BIQUAD_HPF,
50 FILTER_TYPE_BIQUAD_BPF_512,
51 FILTER_TYPE_BIQUAD_BPF_1024,
52 FILTER_TYPE_BIQUAD_BPF_2048
53 };
54
GetFilterTypeString(int type)55 const char* GetFilterTypeString( int type )
56 {
57 const char* FILTER_TYPE_STRING[] =
58 {
59 "NONE",
60 "LPF",
61 "BIQUAD_LPF",
62 "BIQUAD_HPF",
63 "BIQUAD_BPF_512",
64 "BIQUAD_BPF_1024",
65 "BIQUAD_BPF_2048"
66 };
67 if ( type > FILTER_TYPE_BIQUAD_BPF_2048 || type < 0 )
68 {
69 return "INVALID";
70 }
71 return FILTER_TYPE_STRING[ type ];
72 }
73
74 } // anonymous namespace
75
76
77
78 /*---------------------------------------------------------------------------*
79
80 �A�v���P�[�V�����N���X
81
82 *---------------------------------------------------------------------------*/
83 class FilterApp : public nw::snd::demolib::AppBase
84 {
85 protected:
86 virtual void OnInitialize();
87 virtual void OnFinalize();
88 virtual void OnDrawUpLCD( nw::font::TextWriter& );
89 virtual void OnDrawDownLCD( nw::font::TextWriter& );
90 virtual void OnUpdatePad( nw::demo::Pad& );
91 virtual void OnUpdate();
92
93 void SetFilter();
94
95 private:
96 void InitializeSoundSystem();
97
98 nw::snd::RomSoundArchive m_Archive;
99 nw::snd::SoundArchivePlayer m_ArchivePlayer;
100 nw::snd::SoundDataManager m_DataManager;
101 nw::snd::SoundHeap m_Heap;
102 nw::snd::SoundHandle m_Handle;
103
104 void* m_pMemoryForSoundSystem;
105 void* m_pMemoryForInfoBlock;
106 void* m_pMemoryForSoundDataManager;
107 void* m_pMemoryForSoundArchivePlayer;
108 void* m_pMemoryForSoundHeap;
109 void* m_pMemoryForStreamBuffer;
110
111 int m_FilterType;
112 f32 m_LpfValue;
113 f32 m_BiquadFilterValue;
114 };
115
116
117
118 /*---------------------------------------------------------------------------*
119
120 �A�v���P�[�V�����N���X����
121
122 *---------------------------------------------------------------------------*/
OnInitialize()123 void FilterApp::OnInitialize()
124 {
125 InitializeSoundSystem();
126
127 // �T�E���h�f�[�^�̃��[�h
128 if ( ! m_DataManager.LoadData( SEQ_MARIOKART, &m_Heap ) )
129 {
130 NW_ASSERTMSG( false, "LoadData(SEQ_MARIOKART) failed." );
131 }
132 if ( ! m_DataManager.LoadData( SE_YOSHI, &m_Heap ) )
133 {
134 NW_ASSERTMSG( false, "LoadData(SE_YOSHI) failed." );
135 }
136
137 m_FilterType = 0;
138 m_BiquadFilterValue = 0.8f; // �����l
139 m_LpfValue = -0.4f; // �����l
140 }
141
InitializeSoundSystem()142 void FilterApp::InitializeSoundSystem()
143 {
144 // �T�E���h�V�X�e���̏�����
145 {
146 nw::snd::SoundSystem::SoundSystemParam param;
147 size_t workMemSize = nw::snd::SoundSystem::GetRequiredMemSize( param );
148 m_pMemoryForSoundSystem = MemAlloc( workMemSize );
149
150 nw::snd::SoundSystem::Initialize(
151 param,
152 reinterpret_cast<uptr>( m_pMemoryForSoundSystem ),
153 workMemSize );
154 }
155
156 // �T�E���h�A�[�J�C�u�̏�����
157 if ( ! m_Archive.Open( SOUND_ARC_PATH ) )
158 {
159 NW_ASSERTMSG( 0, "cannot open bcsar(%s)\n", SOUND_ARC_PATH );
160 }
161
162 // INFO �u���b�N�̃��[�h
163 {
164 size_t infoBlockSize = m_Archive.GetHeaderSize();
165 m_pMemoryForInfoBlock = MemAlloc( infoBlockSize );
166 if ( ! m_Archive.LoadHeader( m_pMemoryForInfoBlock, infoBlockSize ) )
167 {
168 NW_ASSERTMSG( 0, "cannot load infoBlock(%s)", SOUND_ARC_PATH );
169 }
170 }
171
172 // �T�E���h�f�[�^�}�l�[�W���[�̏�����
173 {
174 size_t setupSize = m_DataManager.GetRequiredMemSize( &m_Archive );
175 m_pMemoryForSoundDataManager = MemAlloc( setupSize );
176 m_DataManager.Initialize( &m_Archive, m_pMemoryForSoundDataManager, setupSize );
177 }
178
179 // �T�E���h�A�[�J�C�u�v���C���[�̏�����
180 {
181 size_t setupSize = m_ArchivePlayer.GetRequiredMemSize( &m_Archive );
182 m_pMemoryForSoundArchivePlayer = MemAlloc( setupSize, 32 );
183 size_t setupStrmBufferSize =
184 m_ArchivePlayer.GetRequiredStreamBufferSize( &m_Archive );
185 m_pMemoryForStreamBuffer = MemAlloc( setupStrmBufferSize, 32 );
186 bool result = m_ArchivePlayer.Initialize(
187 &m_Archive,
188 &m_DataManager,
189 m_pMemoryForSoundArchivePlayer, setupSize,
190 m_pMemoryForStreamBuffer, setupStrmBufferSize );
191 NW_ASSERT( result );
192 }
193
194 // �T�E���h�q�[�v�̍\�z
195 {
196 m_pMemoryForSoundHeap = MemAlloc( SOUND_HEAP_SIZE );
197 bool result = m_Heap.Create( m_pMemoryForSoundHeap, SOUND_HEAP_SIZE );
198 NW_ASSERT( result );
199 }
200 }
201
OnFinalize()202 void FilterApp::OnFinalize()
203 {
204 nw::snd::SoundSystem::Finalize();
205
206 MemFree( m_pMemoryForSoundSystem );
207 MemFree( m_pMemoryForInfoBlock );
208 MemFree( m_pMemoryForSoundDataManager );
209 MemFree( m_pMemoryForSoundArchivePlayer );
210 MemFree( m_pMemoryForSoundHeap );
211 MemFree( m_pMemoryForStreamBuffer );
212 }
213
OnDrawUpLCD(nw::font::TextWriter & writer)214 void FilterApp::OnDrawUpLCD( nw::font::TextWriter& writer )
215 {
216 writer.Printf(" DEMO nw::snd %s\n\n", DEMO_TITLE);
217
218 writer.Print (" -- usage --\n\n");
219 writer.Print (" [A] Play Sequence Sound\n");
220 writer.Print (" [X] Play Wave Sound\n");
221 writer.Print (" [Y] Play Stream Sound\n");
222 writer.Print (" [B] Stop Sound\n");
223 writer.Print (" [LEFT/RIGHT] Change FilterType\n");
224 writer.Print (" [UP/DOWN] Change FilterValue\n\n");
225
226 writer.Print (" -- parameter --\n\n");
227 writer.Printf(" FilterType : %s\n", GetFilterTypeString(m_FilterType));
228 if ( m_FilterType == FILTER_TYPE_LPF )
229 {
230 writer.Printf(" LpfValue : %1.2f\n", m_LpfValue);
231 }
232 else if ( m_FilterType >= FILTER_TYPE_BIQUAD_LPF
233 && m_FilterType <= FILTER_TYPE_BIQUAD_BPF_2048 )
234 {
235 writer.Printf(" BiquadFilterValue: %1.2f\n", m_BiquadFilterValue);
236 }
237 }
238
OnDrawDownLCD(nw::font::TextWriter & writer)239 void FilterApp::OnDrawDownLCD( nw::font::TextWriter& writer )
240 {
241 (void)writer;
242 }
243
OnUpdatePad(nw::demo::Pad & pad)244 void FilterApp::OnUpdatePad( nw::demo::Pad& pad )
245 {
246 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_A ) )
247 {
248 m_Handle.Stop( 0 );
249 bool result = m_ArchivePlayer.StartSound( &m_Handle, SEQ_MARIOKART ).IsSuccess();
250 SetFilter();
251 NN_LOG("[SEQ] SEQ_MARIOKART ... (%d)\n", result);
252 }
253
254 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_X ) )
255 {
256 m_Handle.Stop( 0 );
257 bool result = m_ArchivePlayer.StartSound( &m_Handle, SE_YOSHI ).IsSuccess();
258 SetFilter();
259 NN_LOG("[WSD] SE_YOSHI ... (%d)\n", result);
260 }
261
262 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_Y ) )
263 {
264 m_Handle.Stop( 0 );
265 bool result = m_ArchivePlayer.StartSound( &m_Handle, STRM_MARIOKART ).IsSuccess();
266 SetFilter();
267 NN_LOG("[STRM] STRM_MARIOKART ... (%d)\n", result );
268 }
269
270 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_LEFT ) )
271 {
272 m_FilterType -= 1;
273 if ( m_FilterType < 0 )
274 {
275 m_FilterType = FILTER_TYPE_BIQUAD_BPF_2048;
276 }
277 SetFilter();
278 }
279 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_RIGHT ) )
280 {
281 m_FilterType += 1;
282 if ( m_FilterType > FILTER_TYPE_BIQUAD_BPF_2048 )
283 {
284 m_FilterType = 0;
285 }
286 SetFilter();
287 }
288
289 if ( m_FilterType == FILTER_TYPE_LPF )
290 {
291 if ( pad.IsButtonRepeatFast( nw::demo::Pad::BUTTON_UP ) )
292 {
293 m_LpfValue += LPF_VALUE_DELTA;
294 if ( m_LpfValue > LPF_VALUE_MAX )
295 {
296 m_LpfValue = LPF_VALUE_MAX;
297 }
298 SetFilter();
299 }
300 if ( pad.IsButtonRepeatFast( nw::demo::Pad::BUTTON_DOWN ) )
301 {
302 m_LpfValue -= LPF_VALUE_DELTA;
303 if ( m_LpfValue < LPF_VALUE_MIN )
304 {
305 m_LpfValue = LPF_VALUE_MIN;
306 }
307 SetFilter();
308 }
309 }
310 else if ( m_FilterType >= FILTER_TYPE_BIQUAD_LPF
311 && m_FilterType <= FILTER_TYPE_BIQUAD_BPF_2048 )
312 {
313 if ( pad.IsButtonRepeatFast( nw::demo::Pad::BUTTON_UP ) )
314 {
315 m_BiquadFilterValue += BIQUAD_FILTER_VALUE_DELTA;
316 if ( m_BiquadFilterValue > BIQUAD_FILTER_VALUE_MAX )
317 {
318 m_BiquadFilterValue = BIQUAD_FILTER_VALUE_MAX;
319 }
320 SetFilter();
321 }
322 if ( pad.IsButtonRepeatFast( nw::demo::Pad::BUTTON_DOWN ) )
323 {
324 m_BiquadFilterValue -= BIQUAD_FILTER_VALUE_DELTA;
325 if ( m_BiquadFilterValue < BIQUAD_FILTER_VALUE_MIN )
326 {
327 m_BiquadFilterValue = BIQUAD_FILTER_VALUE_MIN;
328 }
329 SetFilter();
330 }
331 }
332
333 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_B ) )
334 {
335 m_Handle.Stop( 3 );
336 }
337 }
338
OnUpdate()339 void FilterApp::OnUpdate()
340 {
341 m_ArchivePlayer.Update();
342 }
343
SetFilter()344 void FilterApp::SetFilter()
345 {
346 switch ( m_FilterType )
347 {
348 case FILTER_TYPE_NONE:
349 m_Handle.SetLpfFreq( 0.0f );
350 m_Handle.SetBiquadFilter( 0, 0.0f );
351 break;
352 case FILTER_TYPE_LPF:
353 m_Handle.SetLpfFreq( m_LpfValue );
354 m_Handle.SetBiquadFilter( 0, 0.0f );
355 break;
356 case FILTER_TYPE_BIQUAD_LPF:
357 case FILTER_TYPE_BIQUAD_HPF:
358 case FILTER_TYPE_BIQUAD_BPF_512:
359 case FILTER_TYPE_BIQUAD_BPF_1024:
360 case FILTER_TYPE_BIQUAD_BPF_2048:
361 m_Handle.SetLpfFreq( 0.0f );
362 m_Handle.SetBiquadFilter( m_FilterType - 1, m_BiquadFilterValue );
363 break;
364 }
365 }
366
367
368
369 /*---------------------------------------------------------------------------*
370
371 ���C������
372
373 *---------------------------------------------------------------------------*/
nnMain()374 void nnMain()
375 {
376 FilterApp app;
377
378 app.Initialize();
379 app.Run();
380 app.Finalize();
381 }
382