1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_Sound3DEngine.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/snd_Sound3DEngine.h>
19 
20 #include <nw/snd/snd_BasicSound.h>      // nw::snd::SoundAmbientParam
21 
22 namespace nw {
23 namespace snd {
24 
25 /*---------------------------------------------------------------------------*
26   Name:         Sound3DEngine
27 
28   Description:  コンストラクタ
29 
30   Arguments:    None.
31 
32   Returns:      None.
33  *---------------------------------------------------------------------------*/
Sound3DEngine()34 Sound3DEngine::Sound3DEngine()
35 {
36 }
37 
UpdateAmbientParam(const Sound3DManager * sound3DManager,const Sound3DParam * sound3DParam,u32 soundId,u32 updateFlag,SoundAmbientParam * ambientParam)38 void Sound3DEngine::UpdateAmbientParam(
39     const Sound3DManager* sound3DManager,
40     const Sound3DParam* sound3DParam,
41     u32 soundId,
42     u32 updateFlag,
43     SoundAmbientParam* ambientParam
44 )
45 {
46     NW_NULL_ASSERT( sound3DManager );
47     NW_NULL_ASSERT( sound3DParam );
48     NW_NULL_ASSERT( ambientParam );
49 
50     (void)soundId;
51 
52     const Sound3DManager::ListenerList& listenerList = sound3DManager->GetListenerList();
53 
54     // 更新する場合は、最低値で初期化
55     if ( updateFlag & UPDATE_VOLUME )
56     {
57         ambientParam->volume = 0.0f;
58     }
59     if ( updateFlag & UPDATE_PRIORITY )
60     {
61         ambientParam->priority = - sound3DManager->GetMaxPriorityReduction();
62     }
63     if ( updateFlag & UPDATE_FILTER )
64     {
65         ambientParam->biquadFilterValue = 1.0f; // biquad filter 値は最大値で初期化
66     }
67 
68     // マルチリスナー場合、パン・ピッチ計算を行わない
69     if ( listenerList.GetSize() > 1 )
70     {
71         updateFlag &= ~UPDATE_PAN;
72         updateFlag &= ~UPDATE_SPAN;
73         updateFlag &= ~UPDATE_PITCH;
74     }
75 
76     for( Sound3DManager::ListenerList::ConstIterator itr = listenerList.GetBeginIter() ;
77          itr != listenerList.GetEndIter() ; itr++ )
78     {
79         const Sound3DListener& listener = *itr;
80 
81         //------------------------------------------------------------------
82         // 音量/プライオリティ計算
83         if ( updateFlag & ( UPDATE_VOLUME | UPDATE_PRIORITY ) )
84         {
85             f32 volume;
86             int priority;
87             Sound3DCalculator::CalcVolumeAndPriority(
88                 *sound3DManager,
89                 listener,
90                 *sound3DParam,
91                 &volume,
92                 &priority
93             );
94 
95             if ( updateFlag & UPDATE_VOLUME )
96             {
97                 ambientParam->volume = ut::Max( volume, ambientParam->volume );
98             }
99             if ( updateFlag & UPDATE_PRIORITY )
100             {
101                 ambientParam->priority = ut::Max( priority, ambientParam->priority );
102             }
103         }
104 
105         //------------------------------------------------------------------
106         // パン/サラウンドパン計算
107         if ( updateFlag & ( UPDATE_PAN | UPDATE_SPAN ))
108         {
109             f32 pan;
110             f32 span;
111 
112             Sound3DCalculator::CalcPan(
113                 *sound3DManager,
114                 listener,
115                 *sound3DParam,
116                 m_CalcPanParam,
117                 &pan,
118                 &span
119             );
120 
121             if ( updateFlag & UPDATE_PAN )
122             {
123                 ambientParam->pan = pan;
124             }
125             if ( updateFlag & UPDATE_SPAN )
126             {
127                 ambientParam->span = span;
128             }
129         }
130 
131         //------------------------------------------------------------------
132         // ピッチ計算
133         if ( updateFlag & UPDATE_PITCH )
134         {
135             float pitch;
136 
137             Sound3DCalculator::CalcPitch(
138                 *sound3DManager,
139                 listener,
140                 *sound3DParam,
141                 &pitch
142             );
143 
144             ambientParam->pitch = pitch;
145         }
146 
147         //------------------------------------------------------------------
148         // Biquadフィルタ計算
149         if ( updateFlag & UPDATE_FILTER )
150         {
151             float biquadFilterValue;
152 
153             Sound3DCalculator::CalcBiquadFilterValue(
154                 *sound3DManager,
155                 listener,
156                 *sound3DParam,
157                 &biquadFilterValue
158             );
159 
160             ambientParam->biquadFilterType = sound3DManager->GetBiquadFilterType();
161             ambientParam->biquadFilterValue = ut::Min( biquadFilterValue, ambientParam->biquadFilterValue );
162         }
163     }
164 }
165 
UpdateAmbientParam(const Sound3DManager * sound3DManager,const Sound3DParam * sound3DParam,u32 soundId,SoundAmbientParam * ambientParam)166 void Sound3DEngine::UpdateAmbientParam(
167     const Sound3DManager* sound3DManager,
168     const Sound3DParam* sound3DParam,
169     u32 soundId,
170     SoundAmbientParam* ambientParam
171 )
172 {
173     NW_NULL_ASSERT( sound3DManager );
174     NW_NULL_ASSERT( sound3DParam );
175     NW_NULL_ASSERT( ambientParam );
176 
177     u32 updateFlag = 0;
178     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_VOLUME )
179     {
180         updateFlag |= UPDATE_VOLUME;
181     }
182     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_PRIORITY )
183     {
184         updateFlag |= UPDATE_PRIORITY;
185     }
186     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_PAN )
187     {
188         updateFlag |= UPDATE_PAN;
189     }
190     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_SPAN )
191     {
192         updateFlag |= UPDATE_SPAN;
193     }
194     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_FILTER )
195     {
196         updateFlag |= UPDATE_FILTER;
197     }
198     if ( sound3DParam->dopplerFactor > 0 )
199     {
200         updateFlag |= UPDATE_PITCH;
201     }
202 
203     UpdateAmbientParam(
204         sound3DManager,
205         sound3DParam,
206         soundId,
207         updateFlag,
208         ambientParam
209     );
210 }
211 
GetAmbientPriority(const Sound3DManager * sound3DManager,const Sound3DParam * sound3DParam,u32 soundId)212 int Sound3DEngine::GetAmbientPriority(
213     const Sound3DManager* sound3DManager,
214     const Sound3DParam* sound3DParam,
215     u32 soundId
216 )
217 {
218     NW_NULL_ASSERT( sound3DManager );
219     NW_NULL_ASSERT( sound3DParam );
220 
221     u32 updateFlag = UPDATE_START_PRIORITY ;
222     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_PRIORITY )
223     {
224         updateFlag |= UPDATE_PRIORITY;
225     }
226 
227     SoundAmbientParam ambientParam;
228     UpdateAmbientParam(
229         sound3DManager,
230         sound3DParam,
231         soundId,
232         updateFlag,
233         &ambientParam
234     );
235 
236     return ambientParam.priority;
237 }
238 
239 } // namespace nw::snd
240 } // namespace nw
241 
242