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