diff --git a/QuintetPlayer_ja.qm b/QuintetPlayer_ja.qm index 5f1e6e3..ba0758c 100644 Binary files a/QuintetPlayer_ja.qm and b/QuintetPlayer_ja.qm differ diff --git a/QuintetPlayer_ja.ts b/QuintetPlayer_ja.ts index a28ff6b..6bb0c96 100644 --- a/QuintetPlayer_ja.ts +++ b/QuintetPlayer_ja.ts @@ -63,5 +63,10 @@ 13 13人 + + + Usotsuki + 嘘つき + diff --git a/mainwindow.ui b/mainwindow.ui index 7fcf595..d8404fc 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -1193,6 +1193,30 @@ false + + + true + + + + 250 + 10 + 151 + 21 + + + + + Meiryo UI + + + + Usotsuki + + + Qt::AlignCenter + + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2b934d0..3b53693 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -33,7 +33,9 @@ MainWindow::MainWindow(QWidget *parent) : idol_mix_stream = BASS_Mixer_StreamCreate(44100,2,BASS_STREAM_DECODE); BASS_Mixer_StreamAddChannel(mix_stream, idol_mix_stream, 0); - unitsize = 5; + isusotsuki = false; + ui->usotsukilabel->setVisible(false); + oldunitsize = unitsize = 5; idolsel[0] = ui->idolsel0; idolsel[1] = ui->idolsel1; idolsel[2] = ui->idolsel2; @@ -230,6 +232,12 @@ void MainWindow::setBGM(const QString& qStr) { currSong = qStr.toLocal8Bit().constData(); std::string convSongName = readablesong_to_filename[currSong]; + isusotsuki = convSongName == "macpri"; + unitsize = isusotsuki ? 1 : oldunitsize; + ui->usotsukilabel->setVisible(isusotsuki); + ui->soloButton->setVisible(!isusotsuki); + ui->unitButton->setVisible(!isusotsuki); + ui->unitButton13->setVisible(!isusotsuki); BASS_ChannelPause(mix_stream); //dec.wait_for_finish(); BASS_Mixer_ChannelRemove(bgm->get_decode_channel()); @@ -238,7 +246,7 @@ void MainWindow::setBGM(const QString& qStr) BASS_Mixer_StreamAddChannel(mix_stream, bgm->get_decode_channel(), 0); BASS_Mixer_ChannelSetPosition(bgm->get_decode_channel(), 0, BASS_POS_BYTE | BASS_POS_MIXER_RESET); BASS_ChannelSetAttribute(bgm->get_decode_channel(),BASS_ATTRIB_VOL,bgmVol); - parse_control_file(idolInfo, "res/" + convSongName + "/control" + std::to_string(unitsize) + ".txt", idolVol); + parse_control_file(idolInfo, "res/" + convSongName + "/control" + std::to_string(unitsize) + ".txt", idolVol, isusotsuki); for(int i = 0; i < NUM_IDOLS; ++i) { idolsel[i]->blockSignals(true); @@ -337,7 +345,7 @@ void MainWindow::save() dec.wait_for_finish(); // Stream needs to be paused else the output will be garbled BASS_ChannelPause(mix_stream); - export_to_wav(bgm->get_decode_channel(), idoldecodechannels, bgmVol, idolVol, idolInfo, filename); + export_to_wav(bgm->get_decode_channel(), idoldecodechannels, bgmVol, idolVol, idolInfo, filename, isusotsuki); reset(); } @@ -351,7 +359,7 @@ void MainWindow::setIdol(int index) DWORD oldchan = idols[index]->get_decode_channel(); HCAStreamChannel&& hcastream = HCAStreamChannel(&dec); DWORD pos = BASS_ChannelGetPosition(bgm->get_decode_channel(), BASS_POS_BYTE); - hcastream.load("res/" + convSongName + "/" + convIdolName + ".hca", pos/4); + hcastream.load("res/" + convSongName + "/" + convIdolName + ".hca", isusotsuki ? 0 : pos/4); if(index >= unitsize) { hcastream.destroy_channels(); @@ -362,7 +370,17 @@ void MainWindow::setIdol(int index) DWORD position = BASS_ChannelGetPosition(bgm->get_decode_channel(), BASS_POS_BYTE); BASS_ChannelSetPosition(hcastream.get_decode_channel(), position / 2, BASS_POS_BYTE); fuzzy_adjust_vol_pan(hcastream.get_decode_channel(), idolInfo[index]); - BASS_Mixer_StreamAddChannel(idol_mix_stream, hcastream.get_decode_channel(), 0); + if(!isusotsuki) + { + BASS_Mixer_StreamAddChannel(idol_mix_stream, hcastream.get_decode_channel(), 0); + } + else + { + if(index == 0) + { + BASS_Mixer_StreamAddChannel(idol_mix_stream, hcastream.get_decode_channel(), 0); + } + } } // Cleanup wave and channel data if(oldchan != 0) @@ -370,13 +388,21 @@ void MainWindow::setIdol(int index) BASS_Mixer_ChannelRemove(oldchan); } *idols[index] = std::move(hcastream); + if(isusotsuki) + { + QWORD len = BASS_ChannelGetLength(idols[0]->get_decode_channel(), BASS_POS_BYTE); + QWORD mappos = BASS_ChannelGetPosition(bgm->get_decode_channel(), BASS_POS_BYTE) / 2 - 4575494 * 2; + BASS_ChannelSetPosition(idols[0]->get_decode_channel(), mappos >= len || mappos < 0 ? len - 1 : mappos, BASS_POS_BYTE); + BASS_ChannelSetSync(bgm->get_decode_channel(), BASS_SYNC_SETPOS, 0, add_usotsuki, idols[0]); + BASS_ChannelSetSync(bgm->get_decode_channel(), BASS_SYNC_POS, 4575494 * 4, add_usotsuki, idols[0]); + } } void MainWindow::setUnit(bool checked) { if(unitsize!=5 && checked) { - unitsize = 5; + oldunitsize = unitsize = 5; reautomateVolumes(); } } @@ -385,7 +411,7 @@ void MainWindow::setSolo(bool checked) { if(unitsize!=1 && checked) { - unitsize = 1; + oldunitsize = unitsize = 1; reautomateVolumes(); } } @@ -394,7 +420,7 @@ void MainWindow::set13(bool checked) { if(unitsize!=13 && checked) { - unitsize = 13; + oldunitsize = unitsize = 13; reautomateVolumes(); } } @@ -402,7 +428,7 @@ void MainWindow::set13(bool checked) void MainWindow::reautomateVolumes() { std::string convSongName = readablesong_to_filename[currSong]; - parse_control_file(idolInfo, "res/" + convSongName + "/control" + std::to_string(unitsize) + ".txt", idolVol); + parse_control_file(idolInfo, "res/" + convSongName + "/control" + std::to_string(unitsize) + ".txt", idolVol, isusotsuki); for(int i = 0; i < NUM_IDOLS; ++i) { // Don't unload, rather just cleanup channels diff --git a/src/mainwindow.h b/src/mainwindow.h index 19bba7f..f889a15 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -62,6 +62,8 @@ public slots: QLabel* idolimg[NUM_IDOLS]; QPixmap idolpixmap[NUM_IDOLS]; HCADecodeService dec; + bool isusotsuki; + int oldunitsize; }; #endif // MAINWINDOW_H diff --git a/src/utils.cpp b/src/utils.cpp index cc3d3dc..aec35dc 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -5,6 +5,7 @@ #include #include "../bass/bass.h" #include "utils.h" +#include "HCAStreamChannel.h" short safeadd(const short& a, const short& b) { @@ -20,7 +21,7 @@ double clamp(const double& d, const double& lower, const double& upper) return d; } -void export_to_wav(DWORD bgm, DWORD idols[], const double& bgmVol, const double& idolVol, ControlInfo idolControlInfo[], const std::string& filename) +void export_to_wav(DWORD bgm, DWORD idols[], const double& bgmVol, const double& idolVol, ControlInfo idolControlInfo[], const std::string& filename, bool usotsuki) { int pos = 0; short tempbuf[10000]; @@ -75,17 +76,21 @@ void export_to_wav(DWORD bgm, DWORD idols[], const double& bgmVol, const double& idolvolpan[j] = idolControlInfo[j].second[index]; convert_to_left_right(idolvolpan[j], leftVol, rightVol); } - if (!(i % 2)) + if(!usotsuki || (index >= 4575494 && (index - 4575494) * 2 < BASS_ChannelGetLength(idols[j], BASS_POS_BYTE))) { - buf[i] = safeadd(idolVol * leftVol * tempbuf[i / 2], buf[i]); - } - else - { - buf[i] = safeadd(idolVol * rightVol * tempbuf[i / 2], buf[i]); + if (!(i % 2)) + { + buf[i] = safeadd(idolVol * leftVol * tempbuf[i / 2], buf[i]); + } + else + { + buf[i] = safeadd(idolVol * rightVol * tempbuf[i / 2], buf[i]); + } } } } } + fwrite(buf, 1, c, fp); pos = BASS_ChannelGetPosition(bgm, BASS_POS_BYTE); } @@ -101,7 +106,7 @@ void export_to_wav(DWORD bgm, DWORD idols[], const double& bgmVol, const double& fclose(fp); } -void parse_control_file(ControlInfo idolInfo[], const std::string & control_file, double& idolVol) +void parse_control_file(ControlInfo idolInfo[], const std::string & control_file, double& idolVol, bool usotsuki) { double volTable[] = { 0.75, 0.62, 0.55, 0.47, 0.42, 0.39, 0.37, 0.35, 0.33, 0.31, 0.3, 0.29, 0.28 }; VolumePan idolvolpan[NUM_IDOLS]; @@ -126,7 +131,9 @@ void parse_control_file(ControlInfo idolInfo[], const std::string & control_file for (int i = 0; i <= (int)line.length() - 1; ++i) { if(line.at(i) != 'x') - idolvolpan[line.at(i) - 48] = { volTable[numIdols], clamp(-0.15 * ((line.length() - 1) / 2.0 - i), -1, 1) }; + { + idolvolpan[line.at(i) - 48] = { usotsuki ? 1 : volTable[numIdols], clamp(-0.15 * ((line.length() - 1) / 2.0 - i), -1, 1) }; + } } for (int i = 0; i < NUM_IDOLS; ++i) { @@ -170,6 +177,14 @@ void CALLBACK adjust_vol_pan(HSYNC handle, DWORD channel, DWORD data, void* user BASS_ChannelSetAttribute(channel, BASS_ATTRIB_PAN, vp.pan); } +void CALLBACK add_usotsuki(HSYNC handle, DWORD channel, DWORD data, void* user) +{ + DWORD idolchan = ((HCAStreamChannel*)user)->get_decode_channel(); + QWORD len = BASS_ChannelGetLength(idolchan, BASS_POS_BYTE); + QWORD mappos = BASS_ChannelGetPosition(channel, BASS_POS_BYTE) / 2 - 4575494 * 2; + BASS_ChannelSetPosition(idolchan, mappos >= len || mappos < 0 ? len - 1 : mappos, BASS_POS_BYTE); +} + void set_auto_vol_pan_all(ControlInfo idolControlInfo[], DWORD idols[]) { for (int i = 0; i < NUM_IDOLS; ++i) diff --git a/src/utils.h b/src/utils.h index f6d3d82..0189a4a 100644 --- a/src/utils.h +++ b/src/utils.h @@ -15,11 +15,12 @@ typedef std::pair> ControlInfo; short safeadd(const short& a, const short& b); double clamp(const double& d, const double& lower, const double& upper); -void export_to_wav(DWORD bgm, DWORD idols[], const double& bgmVol, const double& idolVol, ControlInfo idolControlInfo[], const std::string& filename); -void parse_control_file(ControlInfo idolInfo[], const std::string& control_file, double& idolVol); +void export_to_wav(DWORD bgm, DWORD idols[], const double& bgmVol, const double& idolVol, ControlInfo idolControlInfo[], const std::string& filename, bool usotsuki); +void parse_control_file(ControlInfo idolInfo[], const std::string& control_file, double& idolVol, bool usotsuki); void convert_to_left_right(VolumePan vp, double& leftVol, double& rightVol); void fuzzy_adjust_vol_pan(DWORD channel, ControlInfo ci); void CALLBACK adjust_vol_pan(HSYNC handle, DWORD channel, DWORD data, void *user); +void CALLBACK add_usotsuki(HSYNC handle, DWORD channel, DWORD data, void* user); void set_auto_vol_pan_all(ControlInfo idolControlInfo[], DWORD idols[]); void set_auto_vol_pan(const ControlInfo& idolControlInfo, DWORD idolchannel); void parse_names(std::unordered_map& readable_to_filename, const std::string& infile, QComboBox* sel[], int size);