1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_HardwareChannel.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_SND_HARDWARE_CHANNEL_
19 #define NW_SND_HARDWARE_CHANNEL_
20 
21 #include <nw/ut/ut_LinkList.h>
22 #include <nw/snd/snd_Global.h>
23 #include <nw/snd/snd_Macro.h>
24 
25 namespace nw {
26 namespace snd {
27 namespace internal {
28 namespace driver {
29 
30 class HardwareChannel
31 {
32     friend class HardwareChannelManager;
33 
34 #ifdef NW_PLATFORM_CTRWIN
35 public:
36     typedef AXVPB           ParameterBlock;
37     typedef AXPBMIX         MixParameterBlock;
38     typedef AXPBADPCM       DspAdpcmParameterBlock;
39     typedef AXPBADPCMLOOP   DspAdpcmLoopParameterBlock;
40 #endif
41 
42 public:
43 
44     // ------------------------------------------------------------------------
45     // コールバック関数
46     enum HardwareChannelCallbackStatus
47     {
48         CALLBACK_STATUS_CANCEL,
49         CALLBACK_STATUS_DROP_DSP
50     };
51 
52     typedef void (*HardwareChannelCallback)(
53         HardwareChannel* hardwareChannel,
54         HardwareChannelCallbackStatus status,
55         void* callbackData
56     );
57 
58 public:
59     typedef u32 DspAddress;
60 
61     static u32 GetSampleByDspAddress(
62         const void* baseAddress,
63         DspAddress addr,
64         SampleFormat format
65     );
66 
67     static void CalcOffsetDspAdpcmParam(
68         u16* outPredScale,
69         u16* outYn1,
70         u16* outYn2,
71         u32 offset,
72         const void* dataAddr,
73         const DspAdpcmParam& adpcmParam
74     );
75 
76 private:
77     static DspAddress GetDspAddressBySample(
78             const void* baseAddress,
79             u32 samples,
80             SampleFormat format );
81 
82 
83 public:
84     HardwareChannel();
85     ~HardwareChannel();
86 
87 
88     void SetParamBlock( ParameterBlock* vpb );
89     void ClearParamBlock();
90 
91     void Initialize( const void* waveAddr, SampleFormat format, int sampleRate );
92     bool IsPlaying() const;
93     bool IsPlayFinished() const;
94 
GetFormat()95     SampleFormat GetFormat() const { return m_Format; }
96 
97     void Run();
98     void Stop();
99     void Sync();
100 
101     // アドレス関連関数
102     void StopAtPoint( const void* baseAddress, u32 samples );
103     void SetLoopStart( const void* baseAddress, u32 samples = 0 );
104     void SetLoopEnd( const void* baseAddress, u32 samples );
SetBaseAddress(const void * baseAddress)105     void SetBaseAddress( const void* baseAddress ) { m_pWaveData = baseAddress; }
106     void SetLoopFlag( bool loopFlag );
107     u32 GetPlayPosition() const;
108     bool IsCurrentAddressCovered( const void* begin, const void* end ) const;
109     bool IsDataAddressCovered( const void* begin, const void* end ) const;
110 
111     // パラメータ設定関数
112     void SetAddr(
113         bool loopFlag,
114         const void* waveAddr,
115         u32 startOffset,
116         u32 loopStart,
117         u32 loopEnd
118     );
119     void SetDspAdpcm( const DspAdpcmParam* param );
120     void SetDspAdpcmLoop( const DspAdpcmLoopParam* param );
121     void SetSrcType( SrcType type, f32 pitch );
122     void SetMixParam( const MixParam& param );
123     void SetSrc( f32 ratio, bool initialUpdate );
124     void SetVolume( f32 volume );
125     void SetLpf( u16 freq );
126     void SetBiquad( u8 filterType, f32 value );
127     void SetPriority( u32 priority );
128 
129     void SetVoiceMix( const MixParameterBlock& mix, bool immediatelySync = false );
130 
IsAvailable()131     bool IsAvailable() const { return m_pVpb != NULL; }
132 
133 private:
134     void Initialize();
135     void OnInitialize();
136 
137     DspAddress GetLoopStartDspAddress() const;
138     DspAddress GetLoopEndDspAddress() const;
139 
140     static void ChannelCallback( void *callbackData );
141 
142     void SetVoiceLoopAddr( u32 addr );
143     void SetVoiceEndAddr( u32 addr );
144     void SetVoiceLoop( u32 loop );
145 
146     static const u16 VOICE_GAIN_MAX = 0x7fff;
147     static const u16 VOLUME_DEFAULT = 0x8000;
148 
149     const void* m_pWaveData;
150     SampleFormat m_Format;
151     int m_SampleRate;
152 
153     bool m_IsReserveForFree;
154 
155     HardwareChannelCallback m_Callback;
156     void* m_pCallbackData;
157 
158     // AxVoiceParamBlock が持っていた値
159     ParameterBlock* m_pVpb;
160     u32     m_SyncFlag;
161     bool    m_IsFirstVeUpdate;
162 
163 public:
164     ut::LinkListNode m_LinkNode;
165 
166 #ifdef NW_PLATFORM_CTRWIN
167 private:
168     DspAddress GetCurrentPlayingDspAddress() const;
169 
170     float GetDspRatio( f32 ratio ) const;
171 #endif
172 
173 };
174 
175 } // namespace nw::snd::internal::driver
176 } // namespace nw::snd::internal
177 } // namespace nw::snd
178 } // namespace nw
179 
180 #endif /* NW_SND_HARDWARE_CHANNEL_ */
181 
182