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