1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_HardwareManager.h
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: 32385 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_SND_HARDWARE_MANAGER_H_
19 #define NW_SND_HARDWARE_MANAGER_H_
20 
21 #include <nw/ut/ut_LinkList.h>
22 #include <nw/snd/snd_Global.h>
23 #include <nw/snd/snd_MoveValue.h>
24 #include <nw/snd/snd_Util.h>
25 #include <nw/snd/snd_Macro.h>
26 #include <nw/snd/snd_FxBase.h>
27 #include <nw/snd/snd_BiquadFilterCallback.h>
28 #include <nw/snd/snd_BiquadFilterPresets.h>
29 
30 namespace nw {
31 namespace snd {
32 namespace internal {
33 namespace driver {
34 
35 class HardwareManager : public Util::Singleton<HardwareManager>
36 {
37 public:
38     typedef void (*HardwareCallback)();
39 
40 public:
41 
42     // 1 オーディオフレームあたり何ミリ秒か?
43     static const u32 SOUND_FRAME_INTERVAL_MSEC = 5;     // 大体の数値
44 
45     // 何ボイスあるか?
46     static const u32 SOUND_VOICE_COUNT = NN_SND_VOICE_NUM;
47 
48     // ------------------------------------------------------------------------
49     // 初期化
50     void Initialize();
IsInitialized()51     bool IsInitialized() { return m_IsInitialized != 0; }
52     void Finalize();
53 
54     void Update();
55 
56     // ------------------------------------------------------------------------
57     // 出力モード
58     void SetOutputMode( OutputMode mode );
GetOutputMode()59     OutputMode GetOutputMode() const { return m_OutputMode; }
60 
61     // ------------------------------------------------------------------------
62     // エフェクト
63 
64     // エフェクト管理
65     typedef ut::LinkList< FxBase, offsetof(FxBase, m_Link) > FxList;
66     static const SampleFormat FX_SAMPLE_FORMAT = SAMPLE_FORMAT_PCM_S32;
67     static const int FX_SAMPLE_RATE = 32728;
68 
69     // エフェクト登録、削除、削除確認
70     bool AppendEffect( AuxBus bus, FxBase* pFx );
71 #ifdef NW_PLATFORM_CTR
72     bool AppendEffect( AuxBus bus, nn::snd::FxDelay* pFx );
73     bool AppendEffect( AuxBus bus, nn::snd::FxReverb* pFx );
74 #endif
75     void ClearEffect( AuxBus bus, int fadeTimes );
IsFinishedClearEffect(AuxBus bus)76     bool IsFinishedClearEffect( AuxBus bus ) const
77     {
78         NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM );
79         return m_AuxFadeVolume[ bus ].IsFinished();
80     }
81 
82     // リターンボリューム
SetAuxReturnVolume(AuxBus bus,f32 volume,int fadeTimes)83     void SetAuxReturnVolume( AuxBus bus, f32 volume, int fadeTimes )
84     {
85         NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM );
86         m_AuxUserVolume[ bus ].SetTarget( volume, fadeTimes );
87     }
GetAuxReturnVolume(AuxBus bus)88     f32 GetAuxReturnVolume( AuxBus bus ) const
89     {
90         NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM );
91         return m_AuxUserVolume[ bus ].GetValue();
92     }
93 
94 #ifdef NW_PLATFORM_CTR
95     // エフェクト負荷計測
GetEffectProcessTick(AuxBus bus)96     nn::os::Tick GetEffectProcessTick( AuxBus bus ) const
97     {
98         return m_EffectProcessTick[ bus ];
99     }
100 #endif
101 
102 
103     // ------------------------------------------------------------------------
104     f32 GetOutputVolume() const;
105 
106     // ------------------------------------------------------------------------
107     // マスターボリューム
108     void SetMasterVolume( float volume, int fadeTimes );
GetMasterVolume()109     f32 GetMasterVolume() const { return m_MasterVolume.GetValue(); }
110 
111     // ------------------------------------------------------------------------
112     // SRC タイプ
113     void SetSrcType( SrcType type );
GetSrcType()114     SrcType GetSrcType() const { return m_SrcType; }
115 
116     // ------------------------------------------------------------------------
117     // Biquad フィルタ
118     void SetBiquadFilterCallback( int type, const BiquadFilterCallback* cb );
GetBiquadFilterCallback(int type)119     const BiquadFilterCallback* GetBiquadFilterCallback( int type )
120     {
121         NW_MINMAX_ASSERT( type, BIQUAD_FILTER_TYPE_NONE, BIQUAD_FILTER_TYPE_USER_MAX );
122         return m_BiquadFilterCallbackTable[ type ];
123     }
124 
125     // ------------------------------------------------------------------------
126     // リセット前準備
127     void PrepareReset();
128     bool IsResetReady() const;
129 
130     u32 GetChannelCount() const;
131 
132     HardwareManager();
133 
134 private:
135     static const u8 AUX_CALLBACK_WAIT_FRAME = 2;
136 #ifdef NW_PLATFORM_CTRWIN
137     static const u16 AUX_RETURN_VOLUME_MAX = 0x8000;
138     static void AuxCallbackFunc( void* data, void* context );
139     typedef void (*AuxCallback)(void *data, void *context);
140 #else
141     static const f32 AUX_RETURN_VOLUME_MAX = 1.0f;
142     static void AuxCallbackFunc( nn::snd::AuxBusData* data, s32 sampleLength, uptr userData );
143     typedef void (*AuxCallback)( nn::snd::AuxBusData* data, s32 sampleLength, uptr userData );
144 #endif
145     static const BiquadFilterLpf        BIQUAD_FILTER_LPF;
146     static const BiquadFilterHpf        BIQUAD_FILTER_HPF;
147     static const BiquadFilterBpf512     BIQUAD_FILTER_BPF_512;
148     static const BiquadFilterBpf1024    BIQUAD_FILTER_BPF_1024;
149     static const BiquadFilterBpf2048    BIQUAD_FILTER_BPF_2048;
150 
151     void FinalizeEffect( AuxBus bus );
GetEffectList(AuxBus bus)152     FxList& GetEffectList( AuxBus bus )
153     {
154         NW_MINMAXLT_ASSERT( bus, AUX_BUS_A, AUX_BUS_A + AUX_BUS_NUM );
155         return m_FxList[ bus ];
156     }
157 
158     bool                m_IsInitialized;
159 
160     OutputMode          m_OutputMode;
161     SrcType             m_SrcType;
162 
163     MoveValue<f32,int>  m_MasterVolume;
164     MoveValue<f32,int>  m_VolumeForReset;
165     MoveValue<f32,int>  m_AuxFadeVolume[ AUX_BUS_NUM ];
166     MoveValue<f32,int>  m_AuxUserVolume[ AUX_BUS_NUM ];
167     FxList              m_FxList[ AUX_BUS_NUM ];
168     AuxCallback         m_AuxCallback[ AUX_BUS_NUM ];    // Initialize 前の登録 CB
169 
170     const BiquadFilterCallback* m_BiquadFilterCallbackTable[BIQUAD_FILTER_TYPE_USER_MAX+1];
171 
172 #ifdef NW_PLATFORM_CTRWIN
173     void*               m_AuxCallbackContext[ AUX_BUS_NUM ];
174     OSTick              m_EffectProcessTick[ AUX_BUS_NUM ];
175 #else
176     uptr                m_AuxCallbackContext[ AUX_BUS_NUM ];
177     nn::os::Tick        m_EffectProcessTick[ AUX_BUS_NUM ];
178 #endif
179 
180     // コールバック登録後、バッファがクリアになるまで待つ
181     // (AUX_CALLBACK_WAIT_FRAME [=2] フレーム)
182     u8 m_AuxCallbackWaitCounter[ AUX_BUS_NUM ];
183 
184 #ifdef NW_PLATFORM_CTRWIN
185 public:
186     struct CallbackListNode
187     {
188         ut::LinkListNode link;
189         HardwareCallback callback;
190     };
191 
192     typedef ut::LinkList< CallbackListNode, offsetof(CallbackListNode,link)> CallbackList;
193 
194 //
195 // プラットフォーム固有のもの
196 //
197 public:
198     static void AxCallbackFunc();
199     static const int ZERO_BUFFER_SIZE = 256;
200 
201     // ------------------------------------------------------------------------
202     // 定期的なコールバック設定 (3msec[等] ごとに呼ばれる)
203     void RegisterCallback( CallbackListNode* node, HardwareCallback callback );
204     void UnregisterCallback( CallbackListNode* node );
205 
206     void* GetZeroBufferAddress();
207 
208 private:
209     static void HardwareCallbackFunc();
210     static void AiDmaCallbackFunc();    // for PrepareReset
211     void PrepareResetProc();            // for PrepareReset
212 
213     CallbackList            m_CallbackList;
214 
215     AXUserCallback          m_PreRegisteredCallback;
216     void*                   m_pZeroBufferAddress;
217     AIDCallback             m_OldAidCallback;
218     vs32                    m_ResetReadyCounter;
219 #endif // NW_PLATFORM_CTRWIN
220 
221 };
222 
223 } // namespace nw::snd::internal::driver
224 } // namespace nw::snd::internal
225 } // namespace nw::snd
226 } // namespace nw
227 
228 
229 #endif /* NW_SND_HARDWARE_MANAGER_H_ */
230 
231