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