summaryrefslogtreecommitdiff
path: root/engine/audio/private/snd_mp3_source.h
blob: 38d6291a8e5c22e2806e427343babda60fd7fa31 (plain) (blame)
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