1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: snd_streamplayer.cpp 3866 2008-11-17 18:58:49Z dj_jl $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "gamedefs.h"
29 #include "snd_local.h"
30
31 // MACROS ------------------------------------------------------------------
32
33 // TYPES -------------------------------------------------------------------
34
35 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
36
37 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
38
39 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
40
41 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
42
43 // PUBLIC DATA DEFINITIONS -------------------------------------------------
44
45 // PRIVATE DATA DEFINITIONS ------------------------------------------------
46
47 // CODE --------------------------------------------------------------------
48
49 //==========================================================================
50 //
51 // VStreamMusicPlayer::Init
52 //
53 //==========================================================================
54
Init()55 void VStreamMusicPlayer::Init()
56 {
57 }
58
59 //==========================================================================
60 //
61 // VStreamMusicPlayer::Shutdown
62 //
63 //==========================================================================
64
Shutdown()65 void VStreamMusicPlayer::Shutdown()
66 {
67 guard(VStreamMusicPlayer::Shutdown);
68 Stop();
69 unguard;
70 }
71
72 //==========================================================================
73 //
74 // VStreamMusicPlayer::Tick
75 //
76 //==========================================================================
77
Tick(float)78 void VStreamMusicPlayer::Tick(float)
79 {
80 guard(VStreamMusicPlayer::Tick);
81 if (!StrmOpened)
82 return;
83 if (Stopping && FinishTime + 1.0 < Sys_Time())
84 {
85 // Finish playback.
86 Stop();
87 return;
88 }
89 if (Paused)
90 {
91 // Pause playback.
92 return;
93 }
94 for (int Len = SoundDevice->GetStreamAvailable(); Len;
95 Len = SoundDevice->GetStreamAvailable())
96 {
97 short* Data = SoundDevice->GetStreamBuffer();
98 int StartPos = 0;
99 while (!Stopping && StartPos < Len)
100 {
101 int SamplesDecoded = Codec->Decode(Data + StartPos * 2, Len - StartPos);
102 StartPos += SamplesDecoded;
103 if (Codec->Finished())
104 {
105 // Stream ended.
106 if (CurrLoop)
107 {
108 // Restart stream.
109 Codec->Restart();
110 }
111 else
112 {
113 // We'll wait for 1 second to finish playing.
114 Stopping = true;
115 FinishTime = Sys_Time();
116 }
117 }
118 else if (StartPos < Len)
119 {
120 // Should never happen.
121 GCon->Log("Stream decoded less but is not finished");
122 Stopping = true;
123 FinishTime = Sys_Time();
124 }
125 }
126 if (Stopping)
127 {
128 memset(Data + StartPos * 2, 0, (Len - StartPos) * 4);
129 }
130 SoundDevice->SetStreamData(Data, Len);
131 }
132 unguard;
133 }
134
135 //==========================================================================
136 //
137 // VStreamMusicPlayer::Play
138 //
139 //==========================================================================
140
Play(VAudioCodec * InCodec,const char * InName,bool InLoop)141 void VStreamMusicPlayer::Play(VAudioCodec* InCodec, const char* InName,
142 bool InLoop)
143 {
144 guard(VStreamMusicPlayer::Play);
145 StrmOpened = SoundDevice->OpenStream(InCodec->SampleRate,
146 InCodec->SampleBits, InCodec->NumChannels);
147 if (!StrmOpened)
148 return;
149 Codec = InCodec;
150 CurrSong = InName;
151 CurrLoop = InLoop;
152 Stopping = false;
153 if (Paused)
154 {
155 Resume();
156 }
157 unguard;
158 }
159
160 //==========================================================================
161 //
162 // VStreamMusicPlayer::Pause
163 //
164 //==========================================================================
165
Pause()166 void VStreamMusicPlayer::Pause()
167 {
168 guard(VStreamMusicPlayer::Pause);
169 if (!StrmOpened)
170 return;
171 SoundDevice->PauseStream();
172 Paused = true;
173 unguard;
174 }
175
176 //==========================================================================
177 //
178 // VStreamMusicPlayer::Resume
179 //
180 //==========================================================================
181
Resume()182 void VStreamMusicPlayer::Resume()
183 {
184 guard(VStreamMusicPlayer::Resume);
185 if (!StrmOpened)
186 return;
187 SoundDevice->ResumeStream();
188 Paused = false;
189 unguard;
190 }
191
192 //==========================================================================
193 //
194 // VStreamMusicPlayer::Stop
195 //
196 //==========================================================================
197
Stop()198 void VStreamMusicPlayer::Stop()
199 {
200 guard(VStreamMusicPlayer::Stop);
201 if (!StrmOpened)
202 return;
203 delete Codec;
204 Codec = NULL;
205 SoundDevice->CloseStream();
206 StrmOpened = false;
207 unguard;
208 }
209
210 //==========================================================================
211 //
212 // VStreamMusicPlayer::IsPlaying
213 //
214 //==========================================================================
215
IsPlaying()216 bool VStreamMusicPlayer::IsPlaying()
217 {
218 guard(VStreamMusicPlayer::IsPlaying);
219 if (!StrmOpened)
220 return false;
221 return true;
222 unguard;
223 }
224