aboutsummaryrefslogtreecommitdiff
path: root/src/aomusicplayer.cpp
diff options
context:
space:
mode:
authorCrystalwarrior <varsash@gmail.com>2019-10-05 20:32:19 +0300
committerCrystalwarrior <varsash@gmail.com>2019-10-05 20:32:19 +0300
commit9f543f9ef7109340142134124e8bda6c9f750a18 (patch)
treec4ac0c87baa62575af1c1b7e7d25776c7e3247fc /src/aomusicplayer.cpp
parent65332f209c9344e1d3f643ebca32a23dd6f31bdf (diff)
I HAVE CONQUERED BASS HELL
BEHOLD, LOOP_START AND LOOP_END MUSIC POINTS! It reads the songname.mp3.txt file, looking for loop_start, loop_length and loop_end in samples MUSIC EFFECTS SYSTEM THAT CAN ***COMMUNICATE WITH THE SERVER***, WOAHHHHHHHHH! RIGHT-CLICK CONTEXT MENUS TO ENABLE/DISABLE SPECIFIC MUSIC EFFECTS MUSIC EFFECTS ENUMS Fix an issue with music looping
Diffstat (limited to 'src/aomusicplayer.cpp')
-rw-r--r--src/aomusicplayer.cpp93
1 files changed, 56 insertions, 37 deletions
diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp
index 8fe6d15d..49cf089c 100644
--- a/src/aomusicplayer.cpp
+++ b/src/aomusicplayer.cpp
@@ -15,7 +15,7 @@ AOMusicPlayer::~AOMusicPlayer()
}
}
-void AOMusicPlayer::play(QString p_song, int channel, bool crossfade)
+void AOMusicPlayer::play(QString p_song, int channel, bool loop, int effect_flags)
{
channel = channel % m_channelmax;
if (channel < 0) //wtf?
@@ -23,8 +23,9 @@ void AOMusicPlayer::play(QString p_song, int channel, bool crossfade)
QString f_path = ao_app->get_music_path(p_song);
unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE;
- if (m_looping)
+ if (loop)
flags |= BASS_SAMPLE_LOOP;
+
DWORD newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
if (ao_app->get_audio_output_device() != "default")
@@ -33,8 +34,8 @@ void AOMusicPlayer::play(QString p_song, int channel, bool crossfade)
QString d_path = f_path + ".txt";
loop_start = 0;
- loop_end = 0;
- if (m_looping && file_exists(d_path)) //Contains loop/etc. information file
+ loop_end = BASS_ChannelGetLength(newstream, BASS_POS_BYTE);
+ if (loop && file_exists(d_path)) //Contains loop/etc. information file
{
QStringList lines = ao_app->read_file(d_path).split("\n");
foreach (QString line, lines)
@@ -46,49 +47,60 @@ void AOMusicPlayer::play(QString p_song, int channel, bool crossfade)
float sample_rate;
BASS_ChannelGetAttribute(newstream, BASS_ATTRIB_FREQ, &sample_rate);
- qDebug() << sample_rate << args[1].trimmed();
+ //Grab number of bytes for sample size
+ int sample_size = 16/8;
+
+ //number of channels (stereo/mono)
+ int num_channels = 2;
+
+ //Calculate the bytes for loop_start/loop_end to use with the sync proc
+ QWORD bytes = static_cast<QWORD>(args[1].trimmed().toFloat() * sample_size * num_channels);
if (arg == "loop_start")
- loop_start = BASS_ChannelSeconds2Bytes(newstream, args[1].trimmed().toDouble() / static_cast<double>(sample_rate));
+ loop_start = bytes;
else if (arg == "loop_length")
- loop_end = loop_start + BASS_ChannelSeconds2Bytes(newstream, args[1].trimmed().toDouble() / static_cast<double>(sample_rate));
+ loop_end = loop_start + bytes;
else if (arg == "loop_end")
- loop_end = BASS_ChannelSeconds2Bytes(newstream, args[1].trimmed().toDouble() / static_cast<double>(sample_rate));
+ loop_end = bytes;
}
qDebug() << "Found data file for song" << p_song << "length" << BASS_ChannelGetLength(newstream, BASS_POS_BYTE) << "loop start" << loop_start << "loop end" << loop_end;
}
- if (crossfade)
+ if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING)
{
DWORD oldstream = m_stream_list[channel];
- //Mute the new sample
- BASS_ChannelSetAttribute(newstream, BASS_ATTRIB_VOL, 0);
- //Crossfade time
- if (BASS_ChannelIsActive(oldstream) == BASS_ACTIVE_PLAYING)
+
+ if (effect_flags & SYNC_POS)
{
- //Fade out the other sample and stop it
- BASS_ChannelSlideAttribute(oldstream, BASS_ATTRIB_VOL|BASS_SLIDE_LOG, -1, 5000);
BASS_ChannelLock(oldstream, true);
//Sync it with the new sample
BASS_ChannelSetPosition(newstream, BASS_ChannelGetPosition(oldstream, BASS_POS_BYTE), BASS_POS_BYTE);
BASS_ChannelLock(oldstream, false);
}
- //Start it
- BASS_ChannelPlay(newstream, false);
- //Fade in our sample
- BASS_ChannelSlideAttribute(newstream, BASS_ATTRIB_VOL, static_cast<float>(m_volume[channel] / 100.0f), 1000);
- m_stream_list[channel] = newstream;
+ if (effect_flags & FADE_OUT)
+ {
+ //Fade out the other sample and stop it (due to -1)
+ BASS_ChannelSlideAttribute(oldstream, BASS_ATTRIB_VOL|BASS_SLIDE_LOG, -1, 4000);
+ }
+ else
+ BASS_ChannelStop(oldstream); //Stop the sample since we don't need it anymore
}
else
- {
BASS_ChannelStop(m_stream_list[channel]);
- m_stream_list[channel] = newstream;
- BASS_ChannelPlay(m_stream_list[channel], false);
- this->set_volume(m_volume[channel], channel);
+
+ m_stream_list[channel] = newstream;
+ BASS_ChannelPlay(m_stream_list[channel], false);
+ if (effect_flags & FADE_IN)
+ {
+ //Fade in our sample
+ BASS_ChannelSetAttribute(newstream, BASS_ATTRIB_VOL, 0);
+ BASS_ChannelSlideAttribute(newstream, BASS_ATTRIB_VOL, static_cast<float>(m_volume[channel] / 100.0f), 1000);
}
+ else
+ this->set_volume(m_volume[channel], channel);
- this->set_looping(m_looping); //Have to do this here due to any crossfading-related changes, etc.
+ this->set_looping(loop); //Have to do this here due to any crossfading-related changes, etc.
}
void AOMusicPlayer::stop(int channel)
@@ -115,29 +127,36 @@ void AOMusicPlayer::set_volume(int p_value, int channel)
void CALLBACK loopProc(HSYNC handle, DWORD channel, DWORD data, void *user)
{
- AOMusicPlayer *self= static_cast<AOMusicPlayer*>(user);
- qDebug() << BASS_ChannelGetPosition(channel, BASS_POS_BYTE);
- BASS_ChannelSetPosition(channel, self->loop_start, BASS_POS_BYTE);
+ QWORD loop_start = *(static_cast<unsigned *>(user));
+ BASS_ChannelLock(channel, true);
+ BASS_ChannelSetPosition(channel, loop_start, BASS_POS_BYTE);
+ BASS_ChannelLock(channel, false);
}
void AOMusicPlayer::set_looping(bool toggle, int channel)
{
m_looping = toggle;
- qDebug() << "looping" << m_looping;
- if (m_looping == false && BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)
+ if (!m_looping)
{
- BASS_ChannelFlags(m_stream_list[channel], 0, BASS_SAMPLE_LOOP); // remove the LOOP flag
+ if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)
+ BASS_ChannelFlags(m_stream_list[channel], 0, BASS_SAMPLE_LOOP); // remove the LOOP flag
BASS_ChannelRemoveSync(m_stream_list[channel], loop_sync[channel]);
+ loop_sync[channel] = 0;
}
- else if (m_looping == true)
+ else
{
BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP); // set the LOOP flag
- BASS_ChannelRemoveSync(m_stream_list[channel], loop_sync[channel]);
- qDebug() << loop_end;
- if (loop_end > 0)
+ if (loop_sync[channel] != 0)
+ {
+ BASS_ChannelRemoveSync(m_stream_list[channel], loop_sync[channel]); //remove the sync
+ loop_sync[channel] = 0;
+ }
+ if (loop_start > 0)
{
- loop_sync[channel] = BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME, loop_end, loopProc, this);
- qDebug() << "Started loop sync";
+ if (loop_end == 0)
+ loop_end = BASS_ChannelGetLength(m_stream_list[channel], BASS_POS_BYTE);
+ if (loop_end > 0) //Don't loop zero length songs even if we're asked to
+ loop_sync[channel] = BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME, loop_end, loopProc, &loop_start);
}
}
}