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