Descent3/music/streamer.cpp

331 lines
7.8 KiB
C++
Raw Normal View History

/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
--- HISTORICAL COMMENTS FOLLOW ---
2024-04-16 03:43:29 +00:00
* $Logfile: /DescentIII/Main/music/streamer.cpp $
* $Revision: 10 $
* $Date: 4/01/99 4:50p $
* $Author: Matt $
*
* Stream interface with sequencer.
*
* $Log: /DescentIII/Main/music/streamer.cpp $
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 10 4/01/99 4:50p Matt
* Took out Warning() function, chaning those calls to mprintf()
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 9 2/26/99 5:26p Samir
* fixes to streaming audio to reflect fix in direct sound mixer.
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 8 12/10/98 10:12a Samir
* uses newer streaming audio library
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 7 12/07/98 11:45a Samir
* hacks to get music system mostly working in DS_8. Will change this
* system so it's a lot cleaner after music demo.
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 6 12/03/98 12:48p Samir
* speed up sequencer so that gap between samples isn't too big.
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 5 11/20/98 5:21p Samir
* added SEND_STRM_NEXT
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 4 11/13/98 2:27p Samir
* new music system.
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 3 8/10/98 5:53p Samir
* improved switching between streams and basic background/combat music.
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 2 7/28/98 5:43p Samir
* reorg of music system.
2024-04-16 18:56:40 +00:00
*
2024-04-16 03:43:29 +00:00
* 1 7/28/98 12:47p Samir
* moved and revamped from sequencer.cpp
*
* $NoKeywords: $
*/
#include "log.h"
2024-04-16 03:43:29 +00:00
#include "music.h"
#include "streamaudio.h"
2024-09-23 00:16:07 +00:00
#include "pserror.h"
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
oms_stream::oms_stream() {}
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
oms_stream::~oms_stream() {}
2024-04-16 03:43:29 +00:00
// processes a stream's events.
2024-04-16 18:56:40 +00:00
void oms_stream::Process(float frmtime) {
oms_q_evt evt, evt2 = {}; // event for use
2024-04-16 18:56:40 +00:00
if (m_timer > 0.0f)
m_timer -= frmtime;
// invalidate current process result.
m_valid_result = false;
if (!processCommand())
return;
// process queue events.
if (!m_q.recv(&evt))
return;
switch (evt.cmd) {
case OMS_STRM_LOAD:
processQLoad((const char *)evt.parm.p);
break;
case OMS_STRM_FADEOUT:
// reset timer for fadeout to 0 volume
STREAM_COMMANDI(OMS_STRM_FADEOUT);
STREAM_TIMER(evt.parm.f);
break;
case OMS_STRM_FADEIN:
// fade in to volume m_maxvol
STREAM_COMMANDI(OMS_STRM_FADEIN);
STREAM_TIMER(evt.parm.f);
break;
case OMS_STRM_STOP:
STREAM_COMMANDI(OMS_STRM_STOP);
m_stream.Stop();
break;
case OMS_STRM_FREE:
STREAM_COMMANDI(OMS_STRM_FREE);
m_stream.Close();
break;
case OMS_STRM_PLAY:
// process queue events.
if (!m_q.recv(&evt2)) {
Int3();
}
STREAM_COMMANDI(OMS_STRM_PLAY, evt2.parm.i);
m_stream.SetLoopCount(evt2.parm.i);
m_stream.SetVolume(evt.parm.f);
m_stream.Play();
break;
case OMS_STRM_SWITCH:
STREAM_COMMANDP(OMS_STRM_SWITCH, evt.parm.p);
m_stream.Stop(true, &m_data.i);
LOG_DEBUG.printf("%d-%d", m_data.i, m_stream.State());
2024-04-16 18:56:40 +00:00
break;
case OMS_STRM_NEXT:
// m_stream.Next((const char *)evt.parm.p);
if (!m_q.recv(&evt2)) {
Int3();
}
m_data.f = evt2.parm.f;
if (!m_q.recv(&evt2)) {
Int3();
}
m_data2.i = evt2.parm.i;
if (!m_q.recv(&evt2)) {
Int3();
}
STREAM_COMMANDP(OMS_STRM_NEXT, evt2.parm.p);
*(bool *)(evt2.parm.p) = true;
break;
}
2024-04-16 03:43:29 +00:00
}
// sends an event to the stream.
2024-04-16 18:56:40 +00:00
void oms_stream::Send(oms_q_evt *evt) { m_q.send(*evt); }
2024-04-16 03:43:29 +00:00
// reset stream.
2024-04-16 18:56:40 +00:00
void oms_stream::Reset(OutrageMusicSeq *seq) {
m_timer = 0.0f;
m_timer_init = 0.0f;
m_maxvol = 1.0f;
m_status.cmd = OMS_STRM_FREE;
m_seq = seq;
m_q.flush();
m_stream.Close();
2024-04-16 03:43:29 +00:00
}
// volume.
2024-04-16 18:56:40 +00:00
void oms_stream::SetVolume(float vol) {
m_maxvol = vol;
m_stream.SetVolume(vol);
2024-04-16 03:43:29 +00:00
}
// processes current command on stream, return false to end processing.
2024-04-16 18:56:40 +00:00
bool oms_stream::processCommand() {
switch (m_status.cmd) {
case OMS_STRM_FADEIN:
// timed fadein to dest volume
if (m_timer <= 0.0f) {
m_stream.SetVolume(m_maxvol);
STREAM_COMMANDI(OMS_STRM_PLAY);
} else {
m_stream.SetVolume(m_maxvol * (m_timer_init - m_timer) / m_timer_init);
}
return false;
case OMS_STRM_FADEOUT:
// timed fadeout to dest volume
if (m_timer <= 0.0f) {
m_stream.SetVolume(0.0f);
STREAM_COMMANDI(OMS_STRM_PLAY);
} else {
m_stream.SetVolume(m_maxvol * m_timer / m_timer_init);
}
return false;
case OMS_STRM_SWITCH:
// if current measure is greater than initial measure at switch, then we will stop
// this stream and send a play command to the current dominant stream.
2024-05-24 15:46:07 +00:00
// mprintf(0, "%d-%d ",m_data.i, m_stream.State());
2024-04-16 18:56:40 +00:00
if (m_data.i || m_stream.State() == STRM_STOPPED || m_stream.State() == STRM_INVALID) {
bool *still_playing = (bool *)m_status.parm.p;
*still_playing = false;
if (m_status.cmd != OMS_STRM_STOP) {
STREAM_COMMANDI(OMS_STRM_STOP);
m_valid_result = true;
m_result.cmd = OMS_STRM_STOP;
}
}
return false;
case OMS_STRM_PLAY:
// check if stream is still playing. if not, then set current stream status and signal
// a normal song end.
if (m_stream.State() == STRM_STOPPED) {
if (m_status.cmd != OMS_STRM_STOP) {
STREAM_COMMANDI(OMS_STRM_STOP);
m_valid_result = true;
m_result.cmd = OMS_STRM_STOP;
return false;
}
}
break;
case OMS_STRM_NEXT:
// if (m_stream.HasNextStarted()) {
// *(bool *)(m_status.parm.p) = false;
// m_stream.SetLoopCount(m_data2.i);
// m_stream.SetVolume(m_data.f);
// STREAM_COMMANDI(OMS_STRM_PLAY, m_data2.i);
// return false;
// }
// else {
// *(bool *)(m_status.parm.p) = true;
// }
break;
}
return true;
2024-04-16 03:43:29 +00:00
}
// processes load song q event.
2024-04-16 18:56:40 +00:00
void oms_stream::processQLoad(const char *fname) {
m_stream.Close();
if (m_stream.Open(fname)) {
STREAM_COMMANDP(OMS_STRM_LOAD, (void *)fname);
m_data.p = (void *)fname;
} else {
LOG_WARNING.printf("OMS: Couldn't load song %s.", fname);
2024-04-16 18:56:40 +00:00
STREAM_COMMANDI(OMS_STRM_FREE);
m_valid_result = true;
m_result.cmd = OMS_EVT_SONGENDED;
m_result.parm.p = (void *)fname;
}
2024-04-16 03:43:29 +00:00
}
// THESE FUNCTIONS SEND EVENTS TO THE STREAM EASILY
2024-04-16 18:56:40 +00:00
void oms_stream::SEND_STRM_LOAD(const char *fname) {
oms_q_evt evt;
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
evt.cmd = OMS_STRM_LOAD;
evt.parm.p = (void *)fname;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}
2024-04-16 18:56:40 +00:00
void oms_stream::SEND_STRM_FADEOUT(float time) {
oms_q_evt evt;
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
evt.cmd = OMS_STRM_FADEOUT;
evt.parm.f = time;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}
2024-04-16 18:56:40 +00:00
void oms_stream::SEND_STRM_FADEIN(float time) {
oms_q_evt evt;
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
evt.cmd = OMS_STRM_FADEIN;
evt.parm.f = time;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}
2024-04-16 18:56:40 +00:00
void oms_stream::SEND_STRM_STOP() {
oms_q_evt evt;
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
evt.cmd = OMS_STRM_STOP;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}
2024-05-24 03:07:26 +00:00
void oms_stream::SEND_STRM_PLAY(float vol, uint8_t count) {
2024-04-16 18:56:40 +00:00
oms_q_evt evt;
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
evt.cmd = OMS_STRM_PLAY;
evt.parm.f = vol;
m_q.send(evt);
evt.cmd = OMS_STRM_PARM;
evt.parm.i = (int)count;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}
2024-04-16 18:56:40 +00:00
void oms_stream::SEND_STRM_FREE() {
oms_q_evt evt;
2024-04-16 03:43:29 +00:00
2024-04-16 18:56:40 +00:00
evt.cmd = OMS_STRM_FREE;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}
2024-04-16 18:56:40 +00:00
void oms_stream::SEND_STRM_SWITCH(bool *switch_flag) {
oms_q_evt evt;
evt.cmd = OMS_STRM_SWITCH;
evt.parm.p = (void *)switch_flag;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}
2024-05-24 03:07:26 +00:00
void oms_stream::SEND_STRM_NEXT(const char *fname, float vol, uint8_t count, bool *switch_flag) {
2024-04-16 18:56:40 +00:00
oms_q_evt evt;
evt.cmd = OMS_STRM_NEXT;
evt.parm.p = (void *)fname;
m_q.send(evt);
evt.cmd = OMS_STRM_PARM;
evt.parm.f = vol;
m_q.send(evt);
evt.cmd = OMS_STRM_PARM;
evt.parm.i = (int)count;
m_q.send(evt);
evt.cmd = OMS_STRM_PARM;
evt.parm.p = (void *)switch_flag;
m_q.send(evt);
2024-04-16 03:43:29 +00:00
}