From 3899dbe0bd82875214ebd676130692120f89a412 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Fri, 20 Sep 2019 05:30:07 +0300 Subject: [PATCH] I dunno what the fuck was I doing for the past 4 hours but I made crossfading music work. Music packets can receive channel to play the song in and the crossfading option too. --- include/aomusicplayer.h | 25 ++++++++--- src/aomusicplayer.cpp | 94 ++++++++++++++++++++++++++++++++--------- src/aosfxplayer.cpp | 2 +- src/courtroom.cpp | 37 +++++++++++++--- 4 files changed, 126 insertions(+), 32 deletions(-) diff --git a/include/aomusicplayer.h b/include/aomusicplayer.h index da47128..8ed0771 100644 --- a/include/aomusicplayer.h +++ b/include/aomusicplayer.h @@ -1,5 +1,6 @@ #ifndef AOMUSICPLAYER_H #define AOMUSICPLAYER_H +#include "file_functions.h" #if defined(BASSAUDIO) #include "bass.h" @@ -19,18 +20,30 @@ public: AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app); virtual ~AOMusicPlayer(); - void play(QString p_song); - void stop(); - void set_volume(int p_value); - void set_looping(bool toggle); + void play(QString p_song, int channel=0, bool crossfade=false); + void stop(int channel=0); + void set_volume(int p_value, int channel=0); + void set_looping(bool toggle, int channel=0); + + //These have to be public for the stupid sync thing +// QWORD loop_start = 0; +// QWORD loop_end = 0; private: QWidget *m_parent; AOApplication *ao_app; - bool m_looping = true; + bool m_looping = false; int m_volume = 0; - HSTREAM m_stream; + + const int m_channelmax = 4; + // Channel 0 = music + // Channel 1 = ambience + // Channel 2 = extra + // Channel 3 = extra + HSTREAM m_stream_list[4]; + +// HSYNC loop_sync; }; #elif defined(QTAUDIO) class AOMusicPlayer diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index 781a90c..f6bcb17 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -1,6 +1,6 @@ #include "aomusicplayer.h" -#if defined(BASSAUDIO) +#ifdef BASSAUDIO AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app) { m_parent = parent; @@ -9,48 +9,104 @@ AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app) AOMusicPlayer::~AOMusicPlayer() { - BASS_ChannelStop(m_stream); + for (int n_stream = 0 ; n_stream < m_channelmax ; ++n_stream) + { + BASS_ChannelStop(m_stream_list[n_stream]); + } } -void AOMusicPlayer::play(QString p_song) +void AOMusicPlayer::play(QString p_song, int channel, bool crossfade) { - BASS_ChannelStop(m_stream); - + channel = channel % m_channelmax; QString f_path = ao_app->get_music_path(p_song); - unsigned int flags = BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE; - m_stream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); +// QString d_path = f_path + ".txt"; + +// if (file_exists(d_path)) //Contains loop/etc. information file +// { +// QStringList lines = ao_app->read_file(d_path).split("\n"); +// foreach (QString line, lines) +// { +// QStringList args = line.split("="); +// if (args.size() < 2) +// continue; +// QString arg = args[0].trimmed(); +// if (arg == "loop_start") +// loop_start = args[1].trimmed().toUInt(); +// else if (arg == "loop_end") +// loop_end = args[1].trimmed().toUInt(); +// } +// qDebug() << "Found data file for song" << p_song << loop_start << loop_end; +// } + + unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE; + DWORD newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); - this->set_volume(m_volume); - this->set_looping(m_looping); if (ao_app->get_audio_output_device() != "default") - BASS_ChannelSetDevice(m_stream, BASS_GetDevice()); - BASS_ChannelPlay(m_stream, false); + BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice()); + + if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING && crossfade) + { + DWORD oldstream = m_stream_list[channel]; + + //Fade out the other sample and stop it + BASS_ChannelSlideAttribute(oldstream, BASS_ATTRIB_VOL|BASS_SLIDE_LOG, -1, 5000); + BASS_ChannelLock(oldstream, true); + //Mute the new sample + BASS_ChannelSetAttribute(newstream, BASS_ATTRIB_VOL, 0); + //Sync it with the new sample + BASS_ChannelSetPosition(newstream, BASS_ChannelGetPosition(oldstream, BASS_POS_BYTE), BASS_POS_BYTE); + //Start it + BASS_ChannelPlay(newstream, false); + //Fade in our sample + BASS_ChannelSlideAttribute(newstream, BASS_ATTRIB_VOL, static_cast(m_volume / 100.0f), 1000); + BASS_ChannelLock(oldstream, false); + m_stream_list[channel] = newstream; + } + else + { + BASS_ChannelStop(m_stream_list[channel]); + m_stream_list[channel] = newstream; + BASS_ChannelPlay(m_stream_list[channel], false); + this->set_volume(m_volume); + } + + this->set_looping(m_looping); //Have to do this here due to any crossfading-related changes, etc. } -void AOMusicPlayer::stop() +void AOMusicPlayer::stop(int channel) { - BASS_ChannelStop(m_stream); + BASS_ChannelStop(m_stream_list[channel]); } -void AOMusicPlayer::set_volume(int p_value) +void AOMusicPlayer::set_volume(int p_value, int channel) { m_volume = p_value; float volume = m_volume / 100.0f; - BASS_ChannelSetAttribute(m_stream, BASS_ATTRIB_VOL, volume); + BASS_ChannelSetAttribute(m_stream_list[channel], BASS_ATTRIB_VOL, volume); } -void AOMusicPlayer::set_looping(bool toggle) +//void CALLBACK loopProc(HSYNC handle, DWORD channel, DWORD data, void *user) +//{ +// AOMusicPlayer *self= static_cast(user); +// qDebug() << BASS_ChannelGetPosition(channel, BASS_POS_BYTE); +// BASS_ChannelSetPosition(channel, self->loop_start, BASS_POS_BYTE); +//} + +void AOMusicPlayer::set_looping(bool toggle, int channel) { m_looping = toggle; - if (BASS_ChannelFlags(m_stream, 0, 0) & BASS_SAMPLE_LOOP) + if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP) { if (m_looping == false) - BASS_ChannelFlags(m_stream, 0, BASS_SAMPLE_LOOP); // remove the LOOP flag + BASS_ChannelFlags(m_stream_list[channel], 0, BASS_SAMPLE_LOOP); // remove the LOOP flag +// BASS_ChannelRemoveSync(m_stream_list[channel], loop_sync); } else { if (m_looping == true) - BASS_ChannelFlags(m_stream, BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP); // set the LOOP flag + BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP); // set the LOOP flag +// if (loop_end > 0 && loop_end < BASS_ChannelGetLength(m_stream_list[channel], BASS_POS_BYTE)) +// loop_sync = BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME, loop_end, loopProc, this); } } #elif defined(QTAUDIO) diff --git a/src/aosfxplayer.cpp b/src/aosfxplayer.cpp index b9410c8..ca2b393 100644 --- a/src/aosfxplayer.cpp +++ b/src/aosfxplayer.cpp @@ -31,7 +31,7 @@ void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, int channel { if (channel == -1) { - if (m_stream_list[channel] != NULL) + if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING) m_channel = (m_channel + 1) % m_channelmax; channel = m_channel; } diff --git a/src/courtroom.cpp b/src/courtroom.cpp index fac564c..4291468 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -2862,12 +2862,28 @@ void Courtroom::handle_song(QStringList *p_contents) if (n_char < 0 || n_char >= char_list.size()) { - music_player->play(f_song); + music_player->set_looping(true); + int channel = 0; + if (p_contents->length() > 3 && p_contents->at(3) != "-1") + music_player->set_looping(false); + + if (p_contents->length() > 4) //eyyy we want to change this song's CHANNEL huh + channel = p_contents->at(4).toInt(); //let the music player handle it if it's bigger than the channel list + + bool crossfade = false; + if (p_contents->length() > 5) //CROSSFADE!? Are you MAD? + { + qDebug() << p_contents->at(5); + crossfade = p_contents->at(5) == "1"; //let the music player handle it if it's bigger than the channel list + } + + music_player->play(f_song, channel, crossfade); } else { QString str_char = char_list.at(n_char).name; QString str_show = char_list.at(n_char).name; + music_player->set_looping(true); if (p_contents->length() > 2) { @@ -2884,11 +2900,14 @@ void Courtroom::handle_song(QStringList *p_contents) { music_player->set_looping(false); } - else - { - music_player->set_looping(true); - } } + int channel = 0; + if (p_contents->length() > 4) //eyyy we want to change this song's CHANNEL huh + channel = p_contents->at(4).toInt(); //let the music player handle it if it's bigger than the channel list + + bool crossfade = false; + if (p_contents->length() > 5) //CROSSFADE!? Are you MAD? + crossfade = p_contents->at(5) == "1"; //let the music player handle it if it's bigger than the channel list if (!mute_map.value(n_char)) { @@ -2902,7 +2921,7 @@ void Courtroom::handle_song(QStringList *p_contents) } append_ic_text(f_song_clear, str_show, true); - music_player->play(f_song); + music_player->play(f_song, channel, crossfade); } } } @@ -4055,6 +4074,12 @@ void Courtroom::on_flip_clicked() void Courtroom::on_additive_clicked() { + if (ui_additive->isChecked()) + { + ui_ic_chat_message->home(false); //move cursor to the start of the message + ui_ic_chat_message->insert(" "); //preface the message by whitespace + ui_ic_chat_message->end(false); //move cursor to the end of the message without selecting anything + } ui_ic_chat_message->setFocus(); }