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