1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: Sound3dApp.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 "Sound3dApp.h"
19 #include "simple.csid"
20
21 namespace
22 {
23
24 const s32 SOUND_THREAD_PRIORITY = 4;
25 const s32 LOAD_THREAD_PRIORITY = 3;
26 const s32 SOUND_HEAP_SIZE = 1 * 1024 * 1024;
27 const char SOUND_ARC_PATH[] = NW_SND_DEMO_PATH_PREFIX "simple.bcsar";
28 const char DEMO_TITLE[] = "Sound3d";
29
30 const f32 CONTROL_PAD_STEP = 0.2f;
31 }
32
OnInitialize()33 void Sound3dApp::OnInitialize()
34 {
35 InitializeSoundSystem();
36
37 // サウンドデータのロード
38 if ( ! m_DataManager.LoadData( SE_SQUARE, &m_Heap ) )
39 {
40 NW_ASSERTMSG( false, "LoadData(SE_SQUARE) failed." );
41 }
42 }
43
InitializeSoundSystem()44 void Sound3dApp::InitializeSoundSystem()
45 {
46 // サウンドシステムの初期化
47 {
48 nw::snd::SoundSystem::SoundSystemParam param;
49 size_t workMemSize = nw::snd::SoundSystem::GetRequiredMemSize( param );
50 m_pMemoryForSoundSystem = MemAlloc( workMemSize );
51
52 nw::snd::SoundSystem::Initialize(
53 param,
54 reinterpret_cast<uptr>( m_pMemoryForSoundSystem ),
55 workMemSize );
56 }
57
58 // サウンドアーカイブの初期化
59 if ( ! m_Archive.Open( SOUND_ARC_PATH ) )
60 {
61 NW_ASSERTMSG( 0, "cannot open bcsar(%s)\n", SOUND_ARC_PATH );
62 }
63
64 // INFO ブロックのロード
65 {
66 size_t infoBlockSize = m_Archive.GetHeaderSize();
67 m_pMemoryForInfoBlock = MemAlloc( infoBlockSize );
68 if ( ! m_Archive.LoadHeader( m_pMemoryForInfoBlock, infoBlockSize ) )
69 {
70 NW_ASSERTMSG( 0, "cannot load infoBlock(%s)", SOUND_ARC_PATH );
71 }
72 }
73
74 // サウンドデータマネージャーの初期化
75 {
76 size_t setupSize = m_DataManager.GetRequiredMemSize( &m_Archive );
77 m_pMemoryForSoundDataManager = MemAlloc( setupSize );
78 m_DataManager.Initialize( &m_Archive, m_pMemoryForSoundDataManager, setupSize );
79 }
80
81 // サウンドアーカイブプレイヤーの初期化
82 {
83 size_t setupSize = m_ArchivePlayer.GetRequiredMemSize( &m_Archive );
84 m_pMemoryForSoundArchivePlayer = MemAlloc( setupSize, 32 );
85 size_t setupStrmBufferSize =
86 m_ArchivePlayer.GetRequiredStreamBufferSize( &m_Archive );
87 m_pMemoryForStreamBuffer = MemAlloc( setupStrmBufferSize, 32 );
88 bool result = m_ArchivePlayer.Initialize(
89 &m_Archive,
90 &m_DataManager,
91 m_pMemoryForSoundArchivePlayer, setupSize,
92 m_pMemoryForStreamBuffer, setupStrmBufferSize );
93 NW_ASSERT( result );
94 }
95
96 // サウンドヒープの構築
97 {
98 m_pMemoryForSoundHeap = MemAlloc( SOUND_HEAP_SIZE );
99 bool result = m_Heap.Create( m_pMemoryForSoundHeap, SOUND_HEAP_SIZE );
100 NW_ASSERT( result );
101 }
102
103 // 3D サウンドマネージャーの初期化
104 {
105 size_t setupSize = m_3dManager.GetRequiredMemSize( &m_Archive );
106 m_pMemoryFor3dManager = MemAlloc( setupSize );
107 m_3dManager.Initialize( &m_Archive, m_pMemoryFor3dManager, setupSize );
108 m_3dManager.SetMaxPriorityReduction( 32 );
109 m_3dManager.SetSonicVelocity( 340.0f / 60 );
110 }
111
112 // 3D サウンドリスナーの初期化
113 {
114 m_3dManager.AddListener( &m_3dListener );
115
116 CalcListenerMatrix( &m_ListenerMtx );
117 m_3dListener.SetMatrix( m_ListenerMtx );
118 m_3dListener.SetMaxVolumeDistance( 5.0f );
119 m_3dListener.SetUnitDistance( 5.0f );
120 m_3dListener.SetInteriorSize( 5.0f );
121 }
122
123 // 3D サウンドアクターの初期化
124 {
125 m_3dActor.Initialize( m_ArchivePlayer, m_3dManager );
126 m_ActorPos = nw::math::VEC3::Zero();
127 m_3dActor.SetPosition( m_ActorPos );
128 }
129 }
130
CalcListenerMatrix(nw::math::MTX34 * mtx)131 void Sound3dApp::CalcListenerMatrix( nw::math::MTX34* mtx )
132 {
133 const nw::math::VEC3 pos( 0.0f, 0.0f, -3.0f ); // リスナーの位置
134 const nw::math::VEC3 upVec( 0.0f, 1.0f, 0.0f ); // リスナーのUp方向ベクトル
135 const f32 degree = 0.0f; // リスナーの向き
136
137 // リスナーの方向ベクトル
138 const nw::math::VEC3 direction(
139 -nw::math::SinDeg( degree ), 0.0f, -nw::math::CosDeg( degree )
140 );
141 nw::math::VEC3 target = pos + direction;
142
143 // リスナー行列生成
144 nw::math::MTX34LookAt( mtx, &pos, &upVec, &target );
145 }
146
OnFinalize()147 void Sound3dApp::OnFinalize()
148 {
149 nw::snd::SoundSystem::Finalize();
150
151 MemFree( m_pMemoryForSoundSystem );
152 MemFree( m_pMemoryForInfoBlock );
153 MemFree( m_pMemoryForSoundDataManager );
154 MemFree( m_pMemoryForSoundArchivePlayer );
155 MemFree( m_pMemoryForSoundHeap );
156 MemFree( m_pMemoryForStreamBuffer );
157 }
158
OnDrawUpLCD(nw::font::TextWriter & writer)159 void Sound3dApp::OnDrawUpLCD( nw::font::TextWriter& writer )
160 {
161 writer.Printf(" DEMO nw::snd %s\n\n", DEMO_TITLE);
162
163 writer.Print (" -- usage --\n\n");
164 writer.Print (" [A] Play Sound (Doppler OFF)\n");
165 writer.Print (" [X] Play Sound (Doppler ON)\n");
166 writer.Print (" [B] Reset Actor Position\n");
167 writer.Print (" [LEFT/RIGHT] Move Actor Position.x\n");
168 writer.Print (" [UP/DOWN] Move Actor Position.z\n\n\n");
169
170 writer.Print (" -- status ---\n\n");
171 writer.Printf(" Actor x:% 2.2f\n", m_ActorPos.x);
172 writer.Printf(" z:% 2.2f\n", m_ActorPos.z);
173 }
174
OnDrawDownLCD(nw::font::TextWriter & writer)175 void Sound3dApp::OnDrawDownLCD( nw::font::TextWriter& writer )
176 {
177 (void)writer;
178 }
179
OnUpdatePad(nw::demo::Pad & pad)180 void Sound3dApp::OnUpdatePad( nw::demo::Pad& pad )
181 {
182 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_A ) )
183 {
184 // ドップラーファクター 0 のサウンド
185 m_3dActor.HoldSound( &m_Handle, SE_SQUARE );
186 }
187 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_X ) )
188 {
189 // ドップラーファクター非 0 のサウンド
190 m_3dActor.HoldSound( &m_Handle, SE_3D_DOPPLER );
191 }
192
193 // 3D サウンドアクター座標をリセット
194 if ( pad.IsButtonDown( nw::demo::Pad::BUTTON_B ) )
195 {
196 m_ActorPos.x = 0.0f;
197 m_ActorPos.z = 0.0f;
198
199 // 位置が飛ぶ時は、ResetPosition関数を呼び出す必要がある
200 m_3dActor.ResetPosition();
201 }
202
203 // 3D サウンドアクターの座標変更
204 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_UP ) )
205 {
206 m_ActorPos.z += -CONTROL_PAD_STEP;
207 }
208 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_DOWN ) )
209 {
210 m_ActorPos.z += CONTROL_PAD_STEP;
211 }
212 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_LEFT ) )
213 {
214 m_ActorPos.x += -CONTROL_PAD_STEP;
215 }
216 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_RIGHT ) )
217 {
218 m_ActorPos.x += CONTROL_PAD_STEP;
219 }
220 #if 0
221 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_L ) ||
222 pad.IsButtonPress( nw::demo::Pad::BUTTON_R ) )
223 {
224 f32 l, r = 0.0f;
225 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_L ) )
226 {
227 l = 1.0f;
228 }
229 if ( pad.IsButtonPress( nw::demo::Pad::BUTTON_R ) )
230 {
231 r = 1.0f;
232 }
233
234 double distance = std::sqrt(
235 m_ActorPos.x * m_ActorPos.x +
236 m_ActorPos.z + m_ActorPos.z );
237 double angle = 0.0f;
238 if ( m_ActorPos.x != 0.0f )
239 {
240 angle = std::atan( m_ActorPos.z / m_ActorPos.x );
241 if ( m_ActorPos.x < 0 ) angle += nw::math::F_PI;
242 }
243 else
244 {
245 angle = ( m_ActorPos.z > 0 ) ? nw::math::F_PI / 2.0f :
246 -nw::math::F_PI / 2.0f;
247 }
248 angle -= l / 360.0f * 2 * nw::math::F_PI * 2;
249 angle += r / 360.0f * 2 * nw::math::F_PI * 2;
250 m_ActorPos.x = static_cast<f32>( std::cos( angle ) * distance );
251 m_ActorPos.z = static_cast<f32>( std::sin( angle ) * distance );
252 }
253 #endif
254 }
255
OnUpdate()256 void Sound3dApp::OnUpdate()
257 {
258 m_3dActor.SetPosition( m_ActorPos );
259 m_ArchivePlayer.Update();
260 }
261