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
22 #include "demolib.h"
23 #include "simple.csid"
24
25 class EffectApp : public nw::snd::demolib::AppBase
26 {
27 protected:
28 virtual void OnInitialize();
29 virtual void OnFinalize();
30 virtual void OnDrawUpLCD( nw::font::TextWriter& );
31 virtual void OnDrawDownLCD( nw::font::TextWriter& );
32 virtual void OnUpdatePad( nw::demo::Pad& );
33 virtual void OnUpdate();
34
35 private:
36 enum EffectType
37 {
38 EFFECT_TYPE_NONE,
39 #ifdef NW_SND_AVAILABLE_NN_EFFECT
40 EFFECT_TYPE_NN_REVERB,
41 EFFECT_TYPE_NN_DELAY,
42 #endif
43 EFFECT_TYPE_NW_REVERB,
44 EFFECT_TYPE_NW_DELAY,
45 EFFECT_TYPE_NUM,
46 EFFECT_TYPE_MAX = EFFECT_TYPE_NW_DELAY
47 };
48
49 void InitializeSoundSystem();
50 void InitializeEffect();
51 void FinalizeEffect();
52 const char* GetEffectTypeString() const;
53
54 nw::snd::RomSoundArchive m_Archive;
55 nw::snd::SoundArchivePlayer m_ArchivePlayer;
56 nw::snd::SoundDataManager m_DataManager;
57 nw::snd::SoundHeap m_Heap;
58 nw::snd::SoundHandle m_Handle;
59
60 nw::snd::FxReverb m_NwFxReverb;
61 nw::snd::FxReverb::Param m_NwFxReverbParam;
62 nw::snd::FxDelay m_NwFxDelay;
63 nw::snd::FxDelay::Param m_NwFxDelayParam;
64
65 #ifdef NW_SND_AVAILABLE_NN_EFFECT
66 nn::snd::FxReverb m_NnFxReverb;
67 nn::snd::FxReverb::Param m_NnFxReverbParam;
68 nn::snd::FxDelay m_NnFxDelay;
69 nn::snd::FxDelay::Param m_NnFxDelayParam;
70 #endif
71
72 void* m_pMemoryForSoundSystem;
73 void* m_pMemoryForInfoBlock;
74 void* m_pMemoryForSoundDataManager;
75 void* m_pMemoryForSoundArchivePlayer;
76 void* m_pMemoryForSoundHeap;
77 void* m_pMemoryForStreamBuffer;
78
79 void* m_pMemoryForNwFxReverb;
80 void* m_pMemoryForNwFxDelay;
81
82 #ifdef NW_SND_AVAILABLE_NN_EFFECT
83 void* m_pMemoryForNnFxReverb;
84 void* m_pMemoryForNnFxDelay;
85 #endif
86
87 int m_EffectType; // enum EffectType
88 int m_PreEffectType;
89 };
90
91
92 namespace
93 {
94
95 const s32 SOUND_THREAD_PRIORITY = 4;
96 const s32 LOAD_THREAD_PRIORITY = 3;
97 const s32 SOUND_HEAP_SIZE = 1 * 1024 * 1024;
98 const char SOUND_ARC_PATH[] = NW_SND_DEMO_PATH_PREFIX "simple.bcsar";
99 const char DEMO_TITLE[] = "Effect";
100
101 }
102
OnInitialize()103 void EffectApp::OnInitialize()
104 {
105 InitializeSoundSystem();
106
107 // �T�E���h�f�[�^�̃��[�h
108 if ( ! m_DataManager.LoadData( SEQ_MARIOKART, &m_Heap ) )
109 {
110 NW_ASSERTMSG( false, "LoadData(SEQ_MARIOKART) failed." );
111 }
112 if ( ! m_DataManager.LoadData( SE_YOSHI, &m_Heap ) )
113 {
114 NW_ASSERTMSG( false, "LoadData(SE_YOSHI) failed." );
115 }
116
117 m_PreEffectType = m_EffectType = 0;
118 }
119
InitializeSoundSystem()120 void EffectApp::InitializeSoundSystem()
121 {
122 // �T�E���h�V�X�e���̏�����
123 {
124 nw::snd::SoundSystem::SoundSystemParam param;
125 size_t workMemSize = nw::snd::SoundSystem::GetRequiredMemSize( param );
126 m_pMemoryForSoundSystem = MemAlloc( workMemSize );
127
128 nw::snd::SoundSystem::Initialize(
129 param,
130 reinterpret_cast<uptr>( m_pMemoryForSoundSystem ),
131 workMemSize );
132 }
133
134 // �T�E���h�A�[�J�C�u�̏�����
135 if ( ! m_Archive.Open( SOUND_ARC_PATH ) )
136 {
137 NW_ASSERTMSG( 0, "cannot open bcsar(%s)\n", SOUND_ARC_PATH );
138 }
139
140 // INFO �u���b�N�̃��[�h
141 {
142 size_t infoBlockSize = m_Archive.GetHeaderSize();
143 m_pMemoryForInfoBlock = MemAlloc( infoBlockSize );
144 if ( ! m_Archive.LoadHeader( m_pMemoryForInfoBlock, infoBlockSize ) )
145 {
146 NW_ASSERTMSG( 0, "cannot load infoBlock(%s)", SOUND_ARC_PATH );
147 }
148 }
149
150 // �T�E���h�f�[�^�}�l�[�W���[�̏�����
151 {
152 size_t setupSize = m_DataManager.GetRequiredMemSize( &m_Archive );
153 m_pMemoryForSoundDataManager = MemAlloc( setupSize );
154 m_DataManager.Initialize( &m_Archive, m_pMemoryForSoundDataManager, setupSize );
155 }
156
157 // �T�E���h�A�[�J�C�u�v���C���[�̏�����
158 {
159 size_t setupSize = m_ArchivePlayer.GetRequiredMemSize( &m_Archive );
160 m_pMemoryForSoundArchivePlayer = MemAlloc( setupSize, 32 );
161 size_t setupStrmBufferSize =
162 m_ArchivePlayer.GetRequiredStreamBufferSize( &m_Archive );
163 m_pMemoryForStreamBuffer = MemAlloc( setupStrmBufferSize, 32 );
164 bool result = m_ArchivePlayer.Initialize(
165 &m_Archive,
166 &m_DataManager,
167 m_pMemoryForSoundArchivePlayer, setupSize,
168 m_pMemoryForStreamBuffer, setupStrmBufferSize );
169 NW_ASSERT( result );
170 }
171
172 // �T�E���h�q�[�v�̍\�z
173 {
174 m_pMemoryForSoundHeap = MemAlloc( SOUND_HEAP_SIZE );
175 bool result = m_Heap.Create( m_pMemoryForSoundHeap, SOUND_HEAP_SIZE );
176 NW_ASSERT( result );
177 }
178 }
179
OnFinalize()180 void EffectApp::OnFinalize()
181 {
182 nw::snd::SoundSystem::ClearEffect( nw::snd::AUX_BUS_A );
183 nw::snd::SoundSystem::ClearEffect( nw::snd::AUX_BUS_B );
184
185 m_NwFxReverb.ReleaseWorkBuffer();
186 m_NwFxDelay.ReleaseWorkBuffer();
187 #ifdef NW_SND_AVAILABLE_NN_EFFECT
188 m_NnFxReverb.ReleaseWorkBuffer();
189 m_NnFxDelay.ReleaseWorkBuffer();
190 #endif
191
192 nw::snd::SoundSystem::Finalize();
193
194 MemFree( m_pMemoryForSoundSystem );
195 MemFree( m_pMemoryForInfoBlock );
196 MemFree( m_pMemoryForSoundDataManager );
197 MemFree( m_pMemoryForSoundArchivePlayer );
198 MemFree( m_pMemoryForSoundHeap );
199 MemFree( m_pMemoryForStreamBuffer );
200
201 MemFree( m_pMemoryForNwFxReverb );
202 MemFree( m_pMemoryForNwFxDelay );
203 #ifdef NW_SND_AVAILABLE_NN_EFFECT
204 MemFree( m_pMemoryForNnFxReverb );
205 MemFree( m_pMemoryForNnFxDelay );
206 #endif
207 }
208
OnDrawUpLCD(nw::font::TextWriter & writer)209 void EffectApp::OnDrawUpLCD( nw::font::TextWriter& writer )
210 {
211 writer.Printf(" DEMO nw::snd %s\n\n", DEMO_TITLE);
212
213 writer.Print (" -- usage --\n\n");
214 writer.Print (" [A] Play Sequence Sound\n");
215 writer.Print (" [X] Play Wave Sound\n");
216 writer.Print (" [Y] Play Stream Sound\n");
217 writer.Print (" [B] Stop Sound\n");
218 writer.Print (" [LEFT/RIGHT] Change Effect\n\n");
219 writer.Printf(" current effect: %s\n\n", GetEffectTypeString() );
220 }
221
OnDrawDownLCD(nw::font::TextWriter & writer)222 void EffectApp::OnDrawDownLCD( nw::font::TextWriter& writer )
223 {
224 (void)writer;
225 }
226
OnUpdatePad(nw::demo::Pad & pad)227 void EffectApp::OnUpdatePad( nw::demo::Pad& pad )
228 {
229 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_A ) )
230 {
231 m_Handle.Stop( 0 );
232 bool result = m_ArchivePlayer.StartSound( &m_Handle, SEQ_MARIOKART ).IsSuccess();
233 nw::snd::SequenceSoundHandle handle( &m_Handle );
234 handle.SetFxSend( nw::snd::AUX_BUS_A, 0.3f );
235 NN_LOG("[SEQ] SEQ_MARIOKART ... (%d)\n", result);
236 }
237
238 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_X ) )
239 {
240 m_Handle.Stop( 0 );
241 bool result = m_ArchivePlayer.StartSound( &m_Handle, SE_YOSHI ).IsSuccess();
242 nw::snd::WaveSoundHandle handle( &m_Handle );
243 handle.SetFxSend( nw::snd::AUX_BUS_A, 0.3f );
244 NN_LOG("[WSD] SE_YOSHI ... (%d)\n", result);
245 }
246
247 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_Y ) )
248 {
249 m_Handle.Stop( 0 );
250 bool result = m_ArchivePlayer.StartSound( &m_Handle, STRM_MARIOKART ).IsSuccess();
251 nw::snd::StreamSoundHandle handle( &m_Handle );
252 handle.SetFxSend( nw::snd::AUX_BUS_A, 0.3f );
253 NN_LOG("[STRM] STRM_MARIOKART ... (%d)\n", result );
254 }
255
256 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_B ) )
257 {
258 m_Handle.Stop( 3 );
259 }
260
261 bool isChangeEffect = false;
262 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_LEFT ) )
263 {
264 m_PreEffectType = m_EffectType;
265 m_EffectType -= 1;
266 if ( m_EffectType < 0 ) { m_EffectType = EFFECT_TYPE_MAX; }
267 isChangeEffect = true;
268 }
269 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_RIGHT ) )
270 {
271 m_PreEffectType = m_EffectType;
272 m_EffectType += 1;
273 if ( m_EffectType > EFFECT_TYPE_MAX ) { m_EffectType = 0; }
274 isChangeEffect = true;
275 }
276
277 if ( isChangeEffect )
278 {
279 FinalizeEffect();
280 InitializeEffect();
281 }
282 }
283
FinalizeEffect()284 void EffectApp::FinalizeEffect()
285 {
286 switch ( m_PreEffectType )
287 {
288 case EFFECT_TYPE_NW_REVERB:
289 nw::snd::SoundSystem::ClearEffect( nw::snd::AUX_BUS_A, 0 );
290 m_NwFxReverb.ReleaseWorkBuffer();
291 break;
292 case EFFECT_TYPE_NW_DELAY:
293 nw::snd::SoundSystem::ClearEffect( nw::snd::AUX_BUS_A, 0 );
294 m_NwFxDelay.ReleaseWorkBuffer();
295 break;
296 #ifdef NW_SND_AVAILABLE_NN_EFFECT
297 case EFFECT_TYPE_NN_REVERB:
298 nw::snd::SoundSystem::ClearEffect( nw::snd::AUX_BUS_A, 0 );
299 m_NnFxReverb.ReleaseWorkBuffer();
300 break;
301 case EFFECT_TYPE_NN_DELAY:
302 nw::snd::SoundSystem::ClearEffect( nw::snd::AUX_BUS_A, 0 );
303 m_NnFxDelay.ReleaseWorkBuffer();
304 break;
305 #endif
306 default:
307 break;
308 }
309 }
310
InitializeEffect()311 void EffectApp::InitializeEffect()
312 {
313 switch ( m_EffectType )
314 {
315 case EFFECT_TYPE_NW_REVERB:
316 // nw::snd::FxReverb �̐ݒ�
317 {
318 nw::snd::FxReverb::FilterSize filterSize;
319 filterSize.m_Comb0 = 20 * 160;
320 filterSize.m_Comb1 = 30 * 160;
321 filterSize.m_AllPass = 13 * 160;
322
323 m_NwFxReverbParam.m_EarlyReflectionTime = 200;
324 m_NwFxReverbParam.m_FusedTime = 1000;
325 m_NwFxReverbParam.m_PreDelayTime = 200;
326 m_NwFxReverbParam.m_pFilterSize = &filterSize;
327 m_NwFxReverb.SetParam( m_NwFxReverbParam );
328 size_t reverbBufferSize = m_NwFxReverb.GetRequiredMemSize();
329 m_pMemoryForNwFxReverb = MemAlloc( reverbBufferSize, 4 );
330 m_NwFxReverb.AssignWorkBuffer(
331 reinterpret_cast<uptr>( m_pMemoryForNwFxReverb ),
332 reverbBufferSize );
333
334 bool result = nw::snd::SoundSystem::AppendEffect( nw::snd::AUX_BUS_A, &m_NwFxReverb );
335 NN_LOG( "NW_REVREB %d\n", result );
336 }
337 break;
338
339 case EFFECT_TYPE_NW_DELAY:
340 // nw::snd::FxDelay �̐ݒ�
341 {
342 m_NwFxDelayParam.m_DelayTime = 400;
343 m_NwFxDelayParam.m_FeedbackGain = 0.4f;
344 m_NwFxDelayParam.m_Damping = 0.3f;
345 m_NwFxDelayParam.m_IsEnableSurround = false;
346
347 m_NwFxDelay.SetParam( m_NwFxDelayParam );
348 size_t delayBufferSize = m_NwFxDelay.GetRequiredMemSize();
349 m_pMemoryForNwFxDelay = MemAlloc( delayBufferSize, 4 );
350 m_NwFxDelay.AssignWorkBuffer(
351 reinterpret_cast<uptr>( m_pMemoryForNwFxDelay ),
352 delayBufferSize );
353
354 bool result = nw::snd::SoundSystem::AppendEffect( nw::snd::AUX_BUS_A, &m_NwFxDelay );
355 NN_LOG( "NW_DELAY %d\n", result );
356 }
357 break;
358
359 #ifdef NW_SND_AVAILABLE_NN_EFFECT
360 case EFFECT_TYPE_NN_REVERB:
361 // nn::snd::FxReverb �̐ݒ�
362 {
363 nn::snd::FxReverb::FilterSize filterSize;
364 filterSize.m_Comb0 = 20 * 160;
365 filterSize.m_Comb1 = 30 * 160;
366 filterSize.m_AllPass = 13 * 160;
367
368 m_NnFxReverbParam.m_EarlyReflectionTime = 200;
369 m_NnFxReverbParam.m_FusedTime = 1000;
370 m_NnFxReverbParam.m_PreDelayTime = 200;
371 m_NnFxReverbParam.m_pFilterSize = &filterSize;
372 m_NnFxReverb.SetParam( m_NnFxReverbParam );
373 size_t reverbBufferSize = m_NnFxReverb.GetRequiredMemSize();
374 m_pMemoryForNnFxReverb = MemAlloc( reverbBufferSize, 4 );
375 m_NnFxReverb.AssignWorkBuffer(
376 reinterpret_cast<uptr>( m_pMemoryForNnFxReverb ),
377 reverbBufferSize );
378
379 bool result = nw::snd::SoundSystem::AppendEffect( nw::snd::AUX_BUS_A, &m_NnFxReverb );
380 NN_LOG( "NN_REVREB %d\n", result );
381 }
382 break;
383
384 case EFFECT_TYPE_NN_DELAY:
385 // nn::snd::FxDelay �̐ݒ�
386 {
387 m_NnFxDelayParam.m_DelayTime = 400;
388 m_NnFxDelayParam.m_FeedbackGain = 0.4f;
389 m_NnFxDelayParam.m_Damping = 0.3f;
390 m_NnFxDelayParam.m_IsEnableSurround = false;
391
392 m_NnFxDelay.SetParam( m_NnFxDelayParam );
393 size_t delayBufferSize = m_NnFxDelay.GetRequiredMemSize();
394 m_pMemoryForNnFxDelay = MemAlloc( delayBufferSize, 4 );
395 m_NnFxDelay.AssignWorkBuffer(
396 reinterpret_cast<uptr>( m_pMemoryForNnFxDelay ),
397 delayBufferSize );
398
399 bool result = nw::snd::SoundSystem::AppendEffect( nw::snd::AUX_BUS_A, &m_NnFxDelay );
400 NN_LOG( "NN_DELAY %d\n", result );
401 }
402 break;
403 #endif
404
405 default:
406 {
407 NN_LOG( "NONE\n");
408 }
409 break;
410 }
411 }
412
OnUpdate()413 void EffectApp::OnUpdate()
414 {
415 m_ArchivePlayer.Update();
416 }
417
GetEffectTypeString() const418 const char* EffectApp::GetEffectTypeString() const
419 {
420 static const char* EFFECT_TYPE_STRING[] =
421 {
422 "NONE",
423 #ifdef NW_SND_AVAILABLE_NN_EFFECT
424 "NN_REVERB",
425 "NN_DELAY",
426 #endif
427 "NW_REVERB",
428 "NW_DELAY"
429 };
430 if ( m_EffectType > EFFECT_TYPE_MAX )
431 {
432 return NULL;
433 }
434 return EFFECT_TYPE_STRING[ m_EffectType ];
435 }
436
nnMain()437 void nnMain()
438 {
439 EffectApp app;
440
441 app.Initialize();
442 app.Run();
443 app.Finalize();
444 }
445