1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2008-2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef NLSOUND_ADPCM_XAUDIO2_H
18 #define NLSOUND_ADPCM_XAUDIO2_H
20 #include "nel/sound/driver/buffer.h"
26 * \brief CAdpcmXAudio2
27 * \date 2008-09-07 03:53GMT
28 * \author Jan Boon (Kaetemi)
29 * CAdpcmXAudio2 is a utility class for realtime streaming and decoding of Intel ADPCM data to an XAudio2 source voice.
31 class CAdpcmXAudio2
: public IXAudio2VoiceCallback
35 /// Source voice to which the data is sent.
36 IXAudio2SourceVoice
*_SourceVoice
;
38 const uint8
*_SourceData
;
43 /// Size in uint8 50ms ADPCM. (50ms 4bit ADPCM in uint8 = _SampleRate / 40)
45 /// Samples for 50ms. Also size in uint16 for 100ms PCM. (50ms 16bit PCM in uint16 = _SampleRate / 20)
47 /// Current position in ADPCM buffer in uint8.
51 IBuffer::TADPCMState _State
;
54 /// Number of buffers.
55 static const uint _BufferNb
= 3;
56 /// Data in buffer (in uint16).
57 static const uint _BufferMax
= 2400;
58 /// Three buffers of up to 50ms of 48kHz 16bit PCM data each.
59 sint16 _Buffer
[_BufferNb
][_BufferMax
];
60 /// Buffer that will be written to next.
62 /// Mutex for cross-thread access from XAudio2 callbacks.
63 NLMISC::CMutex _Mutex
;
64 /// Unique id for buffer.
65 uintptr_t _LastBufferContext
;
67 void *_ValidBufferContext
[_BufferNb
];
69 CAdpcmXAudio2(bool loop
);
70 virtual ~CAdpcmXAudio2();
72 /// Create the source voice, it must have this class as callback stuff.
73 inline void setSourceVoice(IXAudio2SourceVoice
*sourceVoice
) { _SourceVoice
= sourceVoice
; }
75 /// Set looping state.
76 inline void setLooping(bool l
) { _Loop
= l
; }
77 /// Submit the next ADPCM buffer, only 1 buffer can be submitted at a time! Plays as soon as submitted (if sourcevoice is playing).
78 void submitSourceBuffer(CBufferXAudio2
*buffer
);
79 /// Reset the decoder, clear the queued buffer
80 void flushSourceBuffers();
81 /// Returns NULL if the buffer has ended playing, never NULL for loops!
82 inline const uint8
*getSourceData() const { return _SourceData
; }
85 /// (Internal) Process and submit the ADPCM data.
86 void processBuffers();
89 // Called just before this voice's processing pass begins.
90 STDMETHOD_(void, OnVoiceProcessingPassStart
) (THIS_ UINT32 BytesRequired
);
91 // Called just after this voice's processing pass ends.
92 STDMETHOD_(void, OnVoiceProcessingPassEnd
) (THIS
);
93 // Called when this voice has just finished playing a buffer stream
94 // (as marked with the XAUDIO2_END_OF_STREAM flag on the last buffer).
95 STDMETHOD_(void, OnStreamEnd
) (THIS
);
96 // Called when this voice is about to start processing a new buffer.
97 STDMETHOD_(void, OnBufferStart
) (THIS_
void* pBufferContext
);
98 // Called when this voice has just finished processing a buffer.
99 // The buffer can now be reused or destroyed.
100 STDMETHOD_(void, OnBufferEnd
) (THIS_
void* pBufferContext
);
101 // Called when this voice has just reached the end position of a loop.
102 STDMETHOD_(void, OnLoopEnd
) (THIS_
void* pBufferContext
);
103 // Called in the event of a critical error during voice processing,
104 // such as a failing XAPO or an error from the hardware XMA decoder.
105 // The voice may have to be destroyed and re-created to recover from
106 // the error. The callback arguments report which buffer was being
107 // processed when the error occurred, and its HRESULT code.
108 STDMETHOD_(void, OnVoiceError
) (THIS_
void* pBufferContext
, HRESULT Error
);
109 }; /* class CAdpcmXAudio2 */
111 } /* namespace NLSOUND */
113 #endif /* #ifndef NLSOUND_ADPCM_XAUDIO2_H */