diff options
| author | Crystalwarrior <varsash@gmail.com> | 2019-10-05 20:32:41 +0300 |
|---|---|---|
| committer | Crystalwarrior <varsash@gmail.com> | 2019-10-05 20:32:41 +0300 |
| commit | 2956a183b4203d9362d62d05ed251c6f934ef090 (patch) | |
| tree | 3909d31aca9d532912dd8cdedee5349a20cd6450 /src | |
| parent | bc8158cc96dd36a18ba18b0271331463cd81c497 (diff) | |
| parent | 9f543f9ef7109340142134124e8bda6c9f750a18 (diff) | |
Merge branch 'bass-hell'
Diffstat (limited to 'src')
| -rw-r--r-- | src/aomusicplayer.cpp | 135 | ||||
| -rw-r--r-- | src/courtroom.cpp | 78 |
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(); |
