2014-07-23 15:28:20 +00:00
|
|
|
/*
|
|
|
|
** audiostream.h
|
|
|
|
**
|
|
|
|
** This file is part of mkxp.
|
|
|
|
**
|
|
|
|
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
|
|
|
|
**
|
|
|
|
** mkxp 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 2 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** mkxp 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 mkxp. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef AUDIOSTREAM_H
|
|
|
|
#define AUDIOSTREAM_H
|
|
|
|
|
|
|
|
#include "al-util.h"
|
|
|
|
#include "alstream.h"
|
2014-09-30 07:13:12 +00:00
|
|
|
#include "sdl-util.h"
|
2014-07-23 15:28:20 +00:00
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
struct AudioStream
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
std::string filename;
|
|
|
|
float volume;
|
|
|
|
float pitch;
|
|
|
|
} current;
|
|
|
|
|
2014-09-30 07:13:12 +00:00
|
|
|
/* Volumes set by external threads,
|
2014-07-23 15:28:20 +00:00
|
|
|
* such as for fade-in/out.
|
2014-09-30 07:13:12 +00:00
|
|
|
* Multiplied together for final
|
|
|
|
* playback volume. Used with setVolume().
|
|
|
|
* Base is set by play().
|
|
|
|
* External is used by MeWatch */
|
|
|
|
enum VolumeType
|
|
|
|
{
|
|
|
|
Base = 0,
|
|
|
|
FadeOut,
|
|
|
|
FadeIn,
|
|
|
|
External,
|
|
|
|
|
|
|
|
VolumeTypeCount
|
|
|
|
};
|
2014-07-23 15:28:20 +00:00
|
|
|
|
|
|
|
/* Note that 'extPaused' and 'noResumeStop' are
|
|
|
|
* effectively only used with the AudioStream
|
2015-03-22 07:42:43 +00:00
|
|
|
* instance representing the BGM.
|
|
|
|
* They are not AtomicFlags because they're regarded
|
|
|
|
* as part of the underlying stream state, and
|
|
|
|
* always accessed with the stream lock held */
|
2014-07-23 15:28:20 +00:00
|
|
|
|
|
|
|
/* Flag indicating that the MeWatch paused this
|
|
|
|
* (BGM) stream because a ME started playing.
|
|
|
|
* While this flag is set, calls to 'play()'
|
|
|
|
* might open another file, but will not start
|
|
|
|
* the playback stream (the MeWatch will start
|
|
|
|
* it as soon as the ME finished playing). */
|
|
|
|
bool extPaused;
|
|
|
|
|
|
|
|
/* Flag indicating that this stream shouldn't be
|
|
|
|
* started by the MeWatch when it is in stopped
|
|
|
|
* state (eg. because the BGM stream was explicitly
|
|
|
|
* stopped by the user script while the ME was playing.
|
|
|
|
* When a new BGM is started (via 'play()') while an ME
|
|
|
|
* is playing, the file will be loaded without starting
|
|
|
|
* the stream, but we want the MeWatch to start it as
|
|
|
|
* soon as the ME ends, so we unset this flag. */
|
|
|
|
bool noResumeStop;
|
|
|
|
|
|
|
|
ALStream stream;
|
|
|
|
SDL_mutex *streamMut;
|
|
|
|
|
2014-09-30 07:13:12 +00:00
|
|
|
/* Fade out */
|
2014-07-23 15:28:20 +00:00
|
|
|
struct
|
|
|
|
{
|
2014-09-30 07:13:12 +00:00
|
|
|
/* Fade out is in progress */
|
|
|
|
AtomicFlag active;
|
2014-07-23 15:28:20 +00:00
|
|
|
|
|
|
|
/* Request fade thread to finish and
|
|
|
|
* cleanup (like it normally would) */
|
2014-09-30 07:13:12 +00:00
|
|
|
AtomicFlag reqFini;
|
2014-07-23 15:28:20 +00:00
|
|
|
|
|
|
|
/* Request fade thread to terminate
|
|
|
|
* immediately */
|
2014-09-30 07:13:12 +00:00
|
|
|
AtomicFlag reqTerm;
|
2014-07-23 15:28:20 +00:00
|
|
|
|
|
|
|
SDL_Thread *thread;
|
|
|
|
std::string threadName;
|
|
|
|
|
|
|
|
/* Amount of reduced absolute volume
|
|
|
|
* per ms of fade time */
|
|
|
|
float msStep;
|
|
|
|
|
|
|
|
/* Ticks at start of fade */
|
|
|
|
uint32_t startTicks;
|
|
|
|
} fade;
|
|
|
|
|
2014-09-30 07:13:12 +00:00
|
|
|
/* Fade in */
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
AtomicFlag rqFini;
|
|
|
|
AtomicFlag rqTerm;
|
|
|
|
|
|
|
|
SDL_Thread *thread;
|
|
|
|
std::string threadName;
|
|
|
|
|
|
|
|
uint32_t startTicks;
|
|
|
|
} fadeIn;
|
|
|
|
|
2014-07-23 15:28:20 +00:00
|
|
|
AudioStream(ALStream::LoopMode loopMode,
|
|
|
|
const std::string &threadId);
|
|
|
|
~AudioStream();
|
|
|
|
|
|
|
|
void play(const std::string &filename,
|
|
|
|
int volume,
|
|
|
|
int pitch,
|
|
|
|
float offset = 0);
|
|
|
|
void stop();
|
|
|
|
void fadeOut(int duration);
|
|
|
|
|
|
|
|
/* Any access to this classes 'stream' member,
|
|
|
|
* whether state query or modification, must be
|
|
|
|
* protected by a 'lock'/'unlock' pair */
|
|
|
|
void lockStream();
|
|
|
|
void unlockStream();
|
|
|
|
|
2014-09-30 07:13:12 +00:00
|
|
|
void setVolume(VolumeType type, float value);
|
|
|
|
float getVolume(VolumeType type);
|
2014-07-23 15:28:20 +00:00
|
|
|
|
|
|
|
float playingOffset();
|
|
|
|
|
|
|
|
private:
|
2014-09-30 07:13:12 +00:00
|
|
|
float volumes[VolumeTypeCount];
|
2014-07-23 15:28:20 +00:00
|
|
|
void updateVolume();
|
|
|
|
|
2014-09-30 07:13:12 +00:00
|
|
|
void finiFadeOutInt();
|
|
|
|
void startFadeIn();
|
|
|
|
|
|
|
|
void fadeOutThread();
|
|
|
|
void fadeInThread();
|
2014-07-23 15:28:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // AUDIOSTREAM_H
|