aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCrystalwarrior <varsash@gmail.com>2019-10-05 20:32:41 +0300
committerCrystalwarrior <varsash@gmail.com>2019-10-05 20:32:41 +0300
commit2956a183b4203d9362d62d05ed251c6f934ef090 (patch)
tree3909d31aca9d532912dd8cdedee5349a20cd6450 /src
parentbc8158cc96dd36a18ba18b0271331463cd81c497 (diff)
parent9f543f9ef7109340142134124e8bda6c9f750a18 (diff)
Merge branch 'bass-hell'
Diffstat (limited to 'src')
-rw-r--r--src/aomusicplayer.cpp135
-rw-r--r--src/courtroom.cpp78
2 files changed, 144 insertions, 69 deletions
diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp
index b44e2e27..49cf089c 100644
--- a/src/aomusicplayer.cpp
+++ b/src/aomusicplayer.cpp
@@ -15,70 +15,92 @@ 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?
return;
QString f_path = ao_app->get_music_path(p_song);
-// 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;
- 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")
BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice());
- if (crossfade)
+ QString d_path = f_path + ".txt";
+
+ loop_start = 0;
+ 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)
+ {
+ QStringList args = line.split("=");
+ if (args.size() < 2)
+ continue;
+ QString arg = args[0].trimmed();
+
+ float sample_rate;
+ BASS_ChannelGetAttribute(newstream, BASS_ATTRIB_FREQ, &sample_rate);
+
+ //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 = bytes;
+ else if (arg == "loop_length")
+ loop_end = loop_start + bytes;
+ else if (arg == "loop_end")
+ 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 (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)
@@ -103,28 +125,39 @@ 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);
-//}
+void CALLBACK loopProc(HSYNC handle, DWORD channel, DWORD data, void *user)
+{
+ 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;
- if (BASS_ChannelFlags(m_stream_list[channel], 0, 0) & BASS_SAMPLE_LOOP)
+ if (!m_looping)
{
- if (m_looping == false)
- BASS_ChannelFlags(m_stream_list[channel], 0, BASS_SAMPLE_LOOP); // remove the LOOP flag
-// BASS_ChannelRemoveSync(m_stream_list[channel], loop_sync);
+ 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)
- 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);
+ BASS_ChannelFlags(m_stream_list[channel], BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP); // set the LOOP flag
+ 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)
+ {
+ 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);
+ }
}
}
#elif defined(QTAUDIO)
diff --git a/src/courtroom.cpp b/src/courtroom.cpp
index e368a32a..0cf5a32c 100644
--- a/src/courtroom.cpp
+++ b/src/courtroom.cpp
@@ -2822,7 +2822,7 @@ void Courtroom::handle_song(QStringList *p_contents)
bool looping = true;
int channel = 0;
- bool crossfade = false;
+ int effect_flags = 0;
if (n_char < 0 || n_char >= char_list.size())
{
int channel = 0;
@@ -2832,13 +2832,12 @@ void Courtroom::handle_song(QStringList *p_contents)
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
- if (p_contents->length() > 5) //CROSSFADE!? Are you MAD?
+ if (p_contents->length() > 5) //Flags provided to us by server such as Fade In, Fade Out, Sync Pos etc.
{
- crossfade = p_contents->at(5) == "1"; //let the music player handle it if it's bigger than the channel list
+ effect_flags = p_contents->at(5).toInt();
}
- music_player->set_looping(looping, channel);
- music_player->play(f_song, channel, crossfade);
+ music_player->play(f_song, channel, looping, effect_flags);
if (channel == 0)
ui_music_name->setText(f_song);
}
@@ -2863,8 +2862,10 @@ void Courtroom::handle_song(QStringList *p_contents)
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
- 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 (p_contents->length() > 5) //Flags provided to us by server such as Fade In, Fade Out, Sync Pos etc.
+ {
+ effect_flags = p_contents->at(5).toInt();
+ }
if (!mute_map.value(n_char))
{
@@ -2878,8 +2879,8 @@ void Courtroom::handle_song(QStringList *p_contents)
}
append_ic_text(f_song_clear, str_show, true);
- music_player->set_looping(looping, channel);
- music_player->play(f_song, channel, crossfade);
+
+ music_player->play(f_song, channel, looping, effect_flags);
if (channel == 0)
ui_music_name->setText(f_song);
}
@@ -3772,14 +3773,14 @@ void Courtroom::on_music_list_double_clicked(QTreeWidgetItem *p_item, int column
QString p_song = p_item->text(column);
- if (!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_support_enabled)
- {
- ao_app->send_server_packet(new AOPacket("MC#" + p_song + "#" + QString::number(m_cid) + "#" + ui_ic_chat_name->text() + "#%"), false);
- }
- else
- {
- ao_app->send_server_packet(new AOPacket("MC#" + p_song + "#" + QString::number(m_cid) + "#%"), false);
- }
+ QStringList packet_contents;
+ packet_contents.append(p_song);
+ packet_contents.append(QString::number(m_cid));
+ if ((!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_support_enabled) || ao_app->effects_enabled)
+ packet_contents.append(ui_ic_chat_name->text());
+ if (ao_app->effects_enabled)
+ packet_contents.append(QString::number(music_flags));
+ ao_app->send_server_packet(new AOPacket("MC", packet_contents), false);
}
void Courtroom::on_music_list_context_menu_requested(const QPoint &pos)
@@ -3788,9 +3789,50 @@ void Courtroom::on_music_list_context_menu_requested(const QPoint &pos)
menu->addAction(QString("Expand All Categories"), this, SLOT(music_list_expand_all()));
menu->addAction(QString("Collapse All Categories"), this, SLOT(music_list_collapse_all()));
- // menu->addSeparator();
+ menu->addSeparator();
+
+ menu->addAction(new QAction("Fade Out Previous", this));
+ menu->actions().back()->setCheckable(true);
+ menu->actions().back()->setChecked(music_flags & FADE_OUT);
+ connect(menu->actions().back(), SIGNAL(toggled(bool)), this, SLOT(music_fade_out(bool)));
+
+ menu->addAction(new QAction("Fade In", this));
+ menu->actions().back()->setCheckable(true);
+ menu->actions().back()->setChecked(music_flags & FADE_IN);
+ connect(menu->actions().back(), SIGNAL(toggled(bool)), this, SLOT(music_fade_in(bool)));
+
+ menu->addAction(new QAction("Synchronize", this));
+ menu->actions().back()->setCheckable(true);
+ menu->actions().back()->setChecked(music_flags & SYNC_POS);
+ connect(menu->actions().back(), SIGNAL(toggled(bool)), this, SLOT(music_synchronize(bool)));
+
menu->popup(ui_music_list->mapToGlobal(pos));
}
+
+void Courtroom::music_fade_out(bool toggle)
+{
+ if (toggle)
+ music_flags |= FADE_OUT;
+ else
+ music_flags &= ~FADE_OUT;
+}
+
+void Courtroom::music_fade_in(bool toggle)
+{
+ if (toggle)
+ music_flags |= FADE_IN;
+ else
+ music_flags &= ~FADE_IN;
+}
+
+void Courtroom::music_synchronize(bool toggle)
+{
+ if (toggle)
+ music_flags |= SYNC_POS;
+ else
+ music_flags &= ~SYNC_POS;
+}
+
void Courtroom::music_list_expand_all()
{
ui_music_list->expandAll();