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