Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6390763
最新版のコンパイルエラー修正
PaulHowell Oct 11, 2021
f3bbaad
practiceConfigurationにmetronomeを追加
N4k4 Oct 18, 2021
590c044
メトロノーム仮音源
N4k4 Oct 19, 2021
93ccf94
練習モードでメトロノームを鳴らす(強制)
PaulHowell Oct 19, 2021
ff1b521
practiceConfigurationのmetronome設定を反映
PaulHowell Oct 19, 2021
dde24b2
音量設定項目の追加
N4k4 Oct 19, 2021
503ea25
メトロノームのボリューム調整設定を反映
PaulHowell Oct 19, 2021
e8515bd
練習スタート時、RhythmTimerProcessorをstartTimeOffsetに合わせて更新
PaulHowell Oct 21, 2021
fbe417f
メトロノーム音のファイル名をsoundの命名規則に(なんとなく)そろえる
N4k4 Oct 21, 2021
a42889d
リネーム前音源の削除
N4k4 Oct 21, 2021
2b23d30
soundに設定されたものがある場合はそちらをメトローム音として利用
N4k4 Oct 21, 2021
86d042c
freq変更時の、整数丸めによるバグの修正
PaulHowell Oct 21, 2021
f6cf737
practiceConfigurationにmetronomeを追加
N4k4 Oct 18, 2021
5dcc4b3
メトロノーム仮音源
N4k4 Oct 19, 2021
d06e6a5
練習モードでメトロノームを鳴らす(強制)
PaulHowell Oct 19, 2021
f8589a5
practiceConfigurationのmetronome設定を反映
PaulHowell Oct 19, 2021
8f0b972
音量設定項目の追加
N4k4 Oct 19, 2021
3a4b53a
メトロノームのボリューム調整設定を反映
PaulHowell Oct 19, 2021
2dfd134
練習スタート時、RhythmTimerProcessorをstartTimeOffsetに合わせて更新
PaulHowell Oct 21, 2021
5cabac9
メトロノーム音のファイル名をsoundの命名規則に(なんとなく)そろえる
N4k4 Oct 21, 2021
51b7303
リネーム前音源の削除
N4k4 Oct 21, 2021
77dc300
soundに設定されたものがある場合はそちらをメトローム音として利用
N4k4 Oct 21, 2021
5071ea2
freq変更時の、整数丸めによるバグの修正
PaulHowell Oct 21, 2021
d356777
Merge branch 'feature/practice-metronome' of doss-gitlab.eidos.ic.i.u…
N4k4 Nov 8, 2021
9ecb616
Add: Discord RPC option to the launcher.
N4k4 Nov 8, 2021
722419a
Remove Comments
N4k4 Nov 8, 2021
c8b734c
Merge branch 'master' into PracticeMetronome
exch-bms2 Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added defaultsound/m-down.wav
Binary file not shown.
Binary file added defaultsound/m-up.wav
Binary file not shown.
23 changes: 20 additions & 3 deletions src/bms/player/beatoraja/play/BMSPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public class BMSPlayer extends MainState {
private RhythmTimerProcessor rhythm;
private long startpressedtime;

public static Discord discord;
private Metronome metronome;

public BMSPlayer(MainController main, PlayerResource resource) {
super(main);
this.model = resource.getBMSModel();
Expand Down Expand Up @@ -465,7 +468,11 @@ public void create() {
judge.init(model, resource);

rhythm = new RhythmTimerProcessor(model,
(getSkin() instanceof PlaySkin) ? ((PlaySkin) getSkin()).getNoteExpansionRate()[0] != 100 || ((PlaySkin) getSkin()).getNoteExpansionRate()[1] != 100 : false);
(getSkin() instanceof PlaySkin && (((PlaySkin) getSkin()).getNoteExpansionRate()[0] != 100 || ((PlaySkin) getSkin()).getNoteExpansionRate()[1] != 100))
|| autoplay.mode == BMSPlayerMode.Mode.PRACTICE // for Metronome
);

metronome = new Metronome(this, autoplay.mode == BMSPlayerMode.Mode.PRACTICE && practice.getPracticeProperty().metronome);

bga = resource.getBGAManager();

Expand Down Expand Up @@ -602,6 +609,7 @@ public void render() {
PMcharaLastnotes[1] = 0;
starttimeoffset = (property.starttime > 1000 ? property.starttime - 1000 : 0) * 100 / property.freq;
playtime = (property.endtime + 1000) * 100 / property.freq + TIME_MARGIN;
metronome.setEnabled(property.metronome);
bga.prepare(this);
state = STATE_READY;
timer.setTimerOn(TIMER_READY);
Expand All @@ -622,8 +630,9 @@ public void render() {
if (timer.getNowTime(TIMER_READY) > skin.getPlaystart()) {
replayConfig = lanerender.getPlayConfig().clone();
state = STATE_PLAY;
timer.setMicroTimer(TIMER_PLAY, micronow - starttimeoffset * 1000);
timer.setMicroTimer(TIMER_RHYTHM, micronow - starttimeoffset * 1000);
main.setMicroTimer(TIMER_PLAY, micronow - starttimeoffset * 1000);
main.setMicroTimer(TIMER_RHYTHM, micronow - starttimeoffset * 1000);
rhythm.setAtStart(this, practice.getPracticeProperty().freq);

input.setStartTime(micronow + timer.getStartMicroTime() - starttimeoffset * 1000);
input.setKeyLogMarginTime(resource.getMarginTime());
Expand All @@ -641,6 +650,10 @@ public void render() {

rhythm.update(this, deltatime, lanerender.getNowBPM(), property.freq);

if (autoplay.mode == BMSPlayerMode.Mode.PRACTICE) {
metronome.update();
}

final long ptime = timer.getNowTime(TIMER_PLAY);
float g = gauge.getValue();
for(int i = 0; i < gaugelog.length; i++) {
Expand Down Expand Up @@ -1015,6 +1028,10 @@ public ReplayData getOptionInformation() {
return playinfo;
}

public RhythmTimerProcessor getRhythmTimerProcessor() {
return rhythm;
}

public void update(int judge, long time) {
notes = this.judge.getPastNotes();

Expand Down
50 changes: 50 additions & 0 deletions src/bms/player/beatoraja/play/Metronome.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package bms.player.beatoraja.play;


import java.nio.file.Path;

import bms.player.beatoraja.MainState;
import bms.player.beatoraja.audio.AudioDriver;

public class Metronome {

private boolean enabled; // 練習モードか否か等にもよるので、configとは別管理。
private final PracticeConfiguration config;
private final RhythmTimerProcessor rhythm;
private final AudioDriver audio;
private int lastSections = 0;
private int lastQuarterNote = 0;

private final Path downbeatPath;
private final Path upbeatPath;


public Metronome(BMSPlayer main, boolean enabled) {
this.rhythm = main.getRhythmTimerProcessor();
this.audio = main.main.getAudioProcessor();
this.config = main.getPracticeConfiguration();
this.enabled = enabled;

downbeatPath=main.main.getCurrentState().getSoundPaths("m-down.wav", MainState.SoundType.SOUND)[0];
upbeatPath=main.main.getCurrentState().getSoundPaths("m-up.wav", MainState.SoundType.SOUND)[0];

}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

// rhythmのアップデート後に呼ぶ
public void update() {
if (enabled && rhythm != null) {
float volume = config.getPracticeProperty().metronomevolume / 100f;
if (rhythm.getSections() > lastSections) {
audio.play(downbeatPath.toString(), volume, false);
}else if (rhythm.getQuarterNote() > lastQuarterNote) {
audio.play(upbeatPath.toString(), volume, false);
}
lastSections = rhythm.getSections();
lastQuarterNote = rhythm.getQuarterNote();
}
}
}
41 changes: 32 additions & 9 deletions src/bms/player/beatoraja/play/PracticeConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ public void setModel(BMSModel model) {
}

public void processInput(BMSPlayerInputProcessor input) {
final int values = model.getMode().player == 2 ? 12 : 10;
final int values = model.getMode().player == 2 ? 14 : 12;
boolean[] cursor = input.getCursorState();
long[] cursortime = input.getCursorTime();
if (input.isControlKeyPressed(ControlKeys.UP)) {
cursorpos = (cursorpos + values - 1) % values;
}
Expand Down Expand Up @@ -180,13 +182,21 @@ public void processInput(BMSPlayerInputProcessor input) {
property.graphtype = (property.graphtype + 2) % 3;
break;
case 9:
property.metronome = !(property.metronome);
break;
case 10:
if(property.metronomevolume>0){
property.metronomevolume -= 1;
}
break;
case 11:
property.random = (property.random + (model.getMode() == Mode.POPN_5K || model.getMode() == Mode.POPN_9K ? 6 : 9))
% (model.getMode() == Mode.POPN_5K || model.getMode() == Mode.POPN_9K ? 7 : 10);
break;
case 10:
case 12:
property.random2 = (property.random2 + 9) % 10;
break;
case 11:
case 13:
property.doubleop = (property.doubleop + 1) % 2;
break;
}
Expand Down Expand Up @@ -251,12 +261,21 @@ public void processInput(BMSPlayerInputProcessor input) {
property.graphtype = (property.graphtype + 1) % 3;
break;
case 9:
property.random = (property.random + 1) % (model.getMode() == Mode.POPN_5K || model.getMode() == Mode.POPN_9K ? 7 : 10);
property.metronome = !(property.metronome);
break;

case 10:
property.random2 = (property.random2 + 1) % 10;
if(property.metronomevolume<200){
property.metronomevolume += 1;
}
break;
case 11:
property.random = (property.random + 1) % (model.getMode() == Mode.POPN_5K || model.getMode() == Mode.POPN_9K ? 7 : 10);
break;
case 12:
property.random2 = (property.random2 + 1) % 10;
break;
case 13:
property.doubleop = (property.doubleop + 1) % 2;
break;

Expand All @@ -280,14 +299,16 @@ public void draw(Rectangle r, SkinObjectRenderer sprite, long time, MainState st
sprite.draw(titlefont, "TOTAL : " + (int)property.total, x, y - 132, cursorpos == 6 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont, "FREQUENCY : " + property.freq, x, y - 154, cursorpos == 7 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont, "GRAPHTYPE : " + GRAPHTYPE[property.graphtype], x, y - 176, cursorpos == 8 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont, "OPTION-1P : " + RANDOM[property.random], x, y - 198, cursorpos == 9 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont,"METRONOME : "+property.metronome,x,y-198,cursorpos == 9 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont,"METRONOME VOLUME : "+property.metronomevolume,x,y-220,cursorpos == 10 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont, "OPTION-1P : " + RANDOM[property.random], x, y - 242, cursorpos == 11 ? Color.YELLOW : Color.CYAN);
if (model.getMode().player == 2) {
sprite.draw(titlefont, "OPTION-2P : " + RANDOM[property.random2], x, y - 220, cursorpos == 10 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont, "OPTION-DP : " + DPRANDOM[property.doubleop], x, y - 242, cursorpos == 11 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont, "OPTION-2P : " + RANDOM[property.random2], x, y - 266, cursorpos == 12 ? Color.YELLOW : Color.CYAN);
sprite.draw(titlefont, "OPTION-DP : " + DPRANDOM[property.doubleop], x, y - 290, cursorpos == 13 ? Color.YELLOW : Color.CYAN);
}

if (state.resource.mediaLoadFinished()) {
sprite.draw(titlefont, "PRESS 1KEY TO PLAY", x, y - 276, Color.ORANGE);
sprite.draw(titlefont, "PRESS 1KEY TO PLAY", x, y - 312, Color.ORANGE);
}

String[] judge = {"PGREAT :","GREAT :","GOOD :", "BAD :", "POOR :", "KPOOR :"};
Expand Down Expand Up @@ -317,5 +338,7 @@ public static class PracticeProperty {
public int freq = 100;
public double total = 0;
public int graphtype = 0;
public boolean metronome = false;
public int metronomevolume = 30; //パーセント値のint型で持つ
}
}
36 changes: 32 additions & 4 deletions src/bms/player/beatoraja/play/RhythmTimerProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import bms.model.BMSModel;
import bms.model.TimeLine;

import java.util.Arrays;

public class RhythmTimerProcessor {

private long[] sectiontimes;
Expand Down Expand Up @@ -64,21 +66,47 @@ public void update(BMSPlayer player, long deltatime, double nowbpm, int freq) {
rhythmtimer += deltatime * (100 - nowbpm * player.getPlaySpeed() / 60) / 100;
player.timer.setMicroTimer(TIMER_RHYTHM, rhythmtimer);

if(sections < sectiontimes.length && (sectiontimes[sections] * (100 / freq)) <= player.timer.getNowMicroTime(TIMER_PLAY)) {
if(sections < sectiontimes.length && (sectiontimes[sections] * 100 / freq) <= player.main.getNowMicroTime(TIMER_PLAY)) {
sections++;;
player.timer.setTimerOn(TIMER_RHYTHM);
rhythmtimer = micronow;
}
if(quarterNoteTimes.length > 0) {
if(quarterNote < quarterNoteTimes.length && (quarterNoteTimes[quarterNote] * (100 / freq)) <= player.timer.getNowMicroTime(TIMER_PLAY)) {
if(quarterNote < quarterNoteTimes.length && (quarterNoteTimes[quarterNote] * 100 / freq) <= player.main.getNowMicroTime(TIMER_PLAY)) {
quarterNote++;
nowQuarterNoteTime = now;
} else if(quarterNote == quarterNoteTimes.length && ((nowQuarterNoteTime + 60000 / nowbpm) * (100 / freq)) <= now) {
} else if(quarterNote == quarterNoteTimes.length && ((nowQuarterNoteTime + 60000 / nowbpm) * 100 / freq) <= now) {
nowQuarterNoteTime = now;
}
}
}


public void setAtStart(BMSPlayer player, int freq) {
final long now = player.main.getNowTime();
final long micronow = player.main.getNowMicroTime();

rhythmtimer = micronow;
player.main.setMicroTimer(TIMER_RHYTHM, rhythmtimer);
nowQuarterNoteTime = now;

sections = Arrays.binarySearch(sectiontimes, player.main.getNowMicroTime(TIMER_PLAY) * freq / 100) + 1;
if (sections <= 0) sections *= -1;

if (quarterNoteTimes.length != 0) {
quarterNote = Arrays.binarySearch(quarterNoteTimes, player.main.getNowMicroTime(TIMER_PLAY) * freq / 100) + 1;
if (quarterNote <= 0) quarterNote *= -1;
}

}

public int getSections() {
return sections;
}

public int getQuarterNote() {
return quarterNote;
}

public long getNowQuarterNoteTime() {
return nowQuarterNoteTime;
}
Expand Down