1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SND_MP3_SOURCE_H
#define SND_MP3_SOURCE_H
#ifdef _WIN32
#pragma once
#endif
#include "snd_audio_source.h"
#include "snd_wave_data.h"
#include "snd_sfx.h"
class IWaveData;
class CAudioMixer;
abstract_class CAudioSourceMP3 : public CAudioSource
{
public:
CAudioSourceMP3( CSfxTable *pSfx );
CAudioSourceMP3( CSfxTable *pSfx, CAudioSourceCachedInfo *info );
virtual ~CAudioSourceMP3();
// Create an instance (mixer) of this audio source
virtual CAudioMixer *CreateMixer( int initialStreamPosition = 0 ) = 0;
virtual int GetType( void );
virtual void GetCacheData( CAudioSourceCachedInfo *info );
// Provide samples for the mixer. You can point pData at your own data, or if you prefer to copy the data,
// you can copy it into copyBuf and set pData to copyBuf.
virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] ) = 0;
virtual int SampleRate( void );
// Returns true if the source is a voice source.
// This affects the voice_overdrive behavior (all sounds get quieter when
// someone is speaking).
virtual bool IsVoiceSource() { return false; }
virtual int SampleSize( void ) { return 1; }
// Total number of samples in this source. NOTE: Some sources are infinite (mic input), they should return
// a count equal to one second of audio at their current rate.
virtual int SampleCount( void ) { return m_dataSize; }
virtual int Format() { return 0; }
virtual int DataSize( void ) { return 0; }
virtual bool IsLooped( void ) { return false; }
virtual bool IsStereoWav( void ) { return false; }
virtual bool IsStreaming( void ) { return false; }
virtual int GetCacheStatus( void ) { return AUDIO_IS_LOADED; }
virtual void CacheLoad( void ) {}
virtual void CacheUnload( void ) {}
virtual CSentence *GetSentence( void ) { return NULL; }
virtual int ZeroCrossingBefore( int sample ) { return sample; }
virtual int ZeroCrossingAfter( int sample ) { return sample; }
// mixer's references
virtual void ReferenceAdd( CAudioMixer *pMixer );
virtual void ReferenceRemove( CAudioMixer *pMixer );
// check reference count, return true if nothing is referencing this
virtual bool CanDelete( void );
virtual bool IsAsyncLoad();
virtual void CheckAudioSourceCache();
virtual char const *GetFileName();
virtual void SetPlayOnce( bool isPlayOnce ) { m_bIsPlayOnce = isPlayOnce; }
virtual bool IsPlayOnce() { return m_bIsPlayOnce; }
virtual void SetSentenceWord( bool bIsWord ) { m_bIsSentenceWord = bIsWord; }
virtual bool IsSentenceWord() { return m_bIsSentenceWord; }
virtual int SampleToStreamPosition( int samplePosition ) { return 0; }
virtual int StreamToSamplePosition( int streamPosition ) { return 0; }
virtual void SetSentence( CSentence *pSentence );
protected:
//-----------------------------------------------------------------------------
// Purpose:
// Output : byte
//-----------------------------------------------------------------------------
inline byte *GetCachedDataPointer()
{
VPROF("CAudioSourceMP3::GetCachedDataPointer");
CAudioSourceCachedInfo *info = m_AudioCacheHandle.Get( CAudioSource::AUDIO_SOURCE_MP3, m_pSfx->IsPrecachedSound(), m_pSfx, &m_nCachedDataSize );
if ( !info )
{
Assert( !"CAudioSourceMP3::GetCachedDataPointer info == NULL" );
return NULL;
}
return (byte *)info->CachedData();
}
CAudioSourceCachedInfoHandle_t m_AudioCacheHandle;
int m_nCachedDataSize;
protected:
CSfxTable *m_pSfx;
int m_sampleRate;
int m_dataSize;
int m_dataStart;
int m_refCount;
bool m_bIsPlayOnce : 1;
bool m_bIsSentenceWord : 1;
bool m_bCheckedForPendingSentence;
};
//-----------------------------------------------------------------------------
// Purpose: Streaming MP3 file
//-----------------------------------------------------------------------------
class CAudioSourceStreamMP3 : public CAudioSourceMP3, public IWaveStreamSource
{
public:
CAudioSourceStreamMP3( CSfxTable *pSfx );
CAudioSourceStreamMP3( CSfxTable *pSfx, CAudioSourceCachedInfo *info );
~CAudioSourceStreamMP3() {}
bool IsStreaming( void ) OVERRIDE { return true; }
bool IsStereoWav( void ) OVERRIDE { return false; }
CAudioMixer *CreateMixer( int initialStreamPosition = 0 ) OVERRIDE;
int GetOutputData( void **pData, int samplePosition, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] ) OVERRIDE;
// IWaveStreamSource
int UpdateLoopingSamplePosition( int samplePosition ) OVERRIDE
{
return samplePosition;
}
void UpdateSamples( char *pData, int sampleCount ) OVERRIDE {}
int GetLoopingInfo( int *pLoopBlock, int *pNumLeadingSamples, int *pNumTrailingSamples ) OVERRIDE
{
return 0;
}
void Prefetch() OVERRIDE;
private:
CAudioSourceStreamMP3( const CAudioSourceStreamMP3 & ); // not implemented, not accessible
};
class CAudioSourceMP3Cache : public CAudioSourceMP3
{
public:
CAudioSourceMP3Cache( CSfxTable *pSfx );
CAudioSourceMP3Cache( CSfxTable *pSfx, CAudioSourceCachedInfo *info );
~CAudioSourceMP3Cache( void );
int GetCacheStatus( void ) OVERRIDE;
void CacheLoad( void ) OVERRIDE;
void CacheUnload( void ) OVERRIDE;
// NOTE: "samples" are bytes for MP3
int GetOutputData( void **pData, int samplePosition, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] ) OVERRIDE;
CAudioMixer *CreateMixer( int initialStreamPosition = 0 ) OVERRIDE;
CSentence *GetSentence( void ) OVERRIDE;
void Prefetch() OVERRIDE {}
protected:
virtual char *GetDataPointer( void );
memhandle_t m_hCache;
private:
CAudioSourceMP3Cache( const CAudioSourceMP3Cache & );
unsigned int m_bNoSentence : 1;
};
bool Audio_IsMP3( const char *pName );
CAudioSource *Audio_CreateStreamedMP3( CSfxTable *pSfx );
CAudioSource *Audio_CreateMemoryMP3( CSfxTable *pSfx );
#endif // SND_MP3_SOURCE_H
|