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 ) ambientParam->volume = 0.0f;
56     if ( updateFlag & UPDATE_PRIORITY ) ambientParam->priority = - sound3DManager->GetMaxPriorityReduction();
57 
58     // マルチリスナー場合、パン・ピッチ計算を行わない
59     if ( listenerList.GetSize() > 1 )
60     {
61         updateFlag &= ~UPDATE_PAN;
62         updateFlag &= ~UPDATE_SPAN;
63         updateFlag &= ~UPDATE_PITCH;
64     }
65 
66     for( Sound3DManager::ListenerList::ConstIterator itr = listenerList.GetBeginIter() ;
67          itr != listenerList.GetEndIter() ; itr++ )
68     {
69         const Sound3DListener& listener = *itr;
70 
71         //------------------------------------------------------------------
72         // 音量/プライオリティ計算
73         if ( updateFlag & ( UPDATE_VOLUME | UPDATE_PRIORITY ) )
74         {
75             f32 volume;
76             int priority;
77             Sound3DCalculator::CalcVolumeAndPriority(
78                 *sound3DManager,
79                 listener,
80                 *sound3DParam,
81                 &volume,
82                 &priority
83             );
84 
85             if ( updateFlag & UPDATE_VOLUME )
86             {
87                 ambientParam->volume = ut::Max( volume, ambientParam->volume );
88             }
89             if ( updateFlag & UPDATE_PRIORITY )
90             {
91                 ambientParam->priority = ut::Max( priority, ambientParam->priority );
92             }
93         }
94 
95         //------------------------------------------------------------------
96         // パン/サラウンドパン計算
97         if ( updateFlag & ( UPDATE_PAN | UPDATE_SPAN ))
98         {
99             f32 pan;
100             f32 span;
101 
102             Sound3DCalculator::CalcPan(
103                 *sound3DManager,
104                 listener,
105                 *sound3DParam,
106                 m_CalcPanParam,
107                 &pan,
108                 &span
109             );
110 
111             if ( updateFlag & UPDATE_PAN ) ambientParam->pan = pan;
112             if ( updateFlag & UPDATE_SPAN ) ambientParam->span = span;
113         }
114 
115         //------------------------------------------------------------------
116         // ピッチ計算
117         if ( updateFlag & UPDATE_PITCH )
118         {
119             float pitch;
120 
121             Sound3DCalculator::CalcPitch(
122                 *sound3DManager,
123                 listener,
124                 *sound3DParam,
125                 &pitch
126             );
127 
128             ambientParam->pitch = pitch;
129         }
130 
131         //------------------------------------------------------------------
132         // Biquadフィルタ計算
133         if ( updateFlag & UPDATE_FILTER )
134         {
135             float biquadFilterValue;
136 
137             Sound3DCalculator::CalcBiquadFilterValue(
138                 *sound3DManager,
139                 listener,
140                 *sound3DParam,
141                 &biquadFilterValue
142             );
143 
144             ambientParam->biquadFilterType = sound3DManager->GetBiquadFilterType();
145             ambientParam->biquadFilterValue = ut::Min( biquadFilterValue, ambientParam->biquadFilterValue );
146         }
147     }
148 }
149 
UpdateAmbientParam(const Sound3DManager * sound3DManager,const Sound3DParam * sound3DParam,u32 soundId,SoundAmbientParam * ambientParam)150 void Sound3DEngine::UpdateAmbientParam(
151     const Sound3DManager* sound3DManager,
152     const Sound3DParam* sound3DParam,
153     u32 soundId,
154     SoundAmbientParam* ambientParam
155 )
156 {
157     NW_NULL_ASSERT( sound3DManager );
158     NW_NULL_ASSERT( sound3DParam );
159     NW_NULL_ASSERT( ambientParam );
160 
161     u32 updateFlag = 0;
162     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_VOLUME )
163     {
164         updateFlag |= UPDATE_VOLUME;
165     }
166     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_PRIORITY )
167     {
168         updateFlag |= UPDATE_PRIORITY;
169     }
170     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_PAN )
171     {
172         updateFlag |= UPDATE_PAN;
173     }
174     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_SPAN )
175     {
176         updateFlag |= UPDATE_SPAN;
177     }
178     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_FILTER )
179     {
180         updateFlag |= UPDATE_FILTER;
181     }
182     if ( sound3DParam->dopplerFactor > 0 )
183     {
184         updateFlag |= UPDATE_PITCH;
185     }
186 
187     UpdateAmbientParam(
188         sound3DManager,
189         sound3DParam,
190         soundId,
191         updateFlag,
192         ambientParam
193     );
194 }
195 
GetAmbientPriority(const Sound3DManager * sound3DManager,const Sound3DParam * sound3DParam,u32 soundId)196 int Sound3DEngine::GetAmbientPriority(
197     const Sound3DManager* sound3DManager,
198     const Sound3DParam* sound3DParam,
199     u32 soundId
200 )
201 {
202     NW_NULL_ASSERT( sound3DManager );
203     NW_NULL_ASSERT( sound3DParam );
204 
205     u32 updateFlag = UPDATE_START_PRIORITY ;
206     if ( sound3DParam->ctrlFlag & SoundArchive::Sound3DInfo::FLAG_CTRL_PRIORITY )
207     {
208         updateFlag |= UPDATE_PRIORITY;
209     }
210 
211     SoundAmbientParam ambientParam;
212     UpdateAmbientParam(
213         sound3DManager,
214         sound3DParam,
215         soundId,
216         updateFlag,
217         &ambientParam
218     );
219 
220     return ambientParam.priority;
221 }
222 
223 } // namespace nw::snd
224 } // namespace nw
225 
226