Skip to content

Commit 478679f

Browse files
authored
Rework state handling of one-time-midi (#787)
1 parent 0601ee6 commit 478679f

File tree

13 files changed

+281
-145
lines changed

13 files changed

+281
-145
lines changed

src.csharp/AlphaTab.Windows/NAudioSynthOutput.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,14 @@ private void RequestBuffers()
128128
public override int Read(float[] buffer, int offset, int count)
129129
{
130130
var read = new Float32Array(count);
131-
_circularBuffer.Read(read, 0, System.Math.Min(read.Length, _circularBuffer.Count));
131+
132+
var samplesFromBuffer = _circularBuffer.Read(read, 0, System.Math.Min(read.Length, _circularBuffer.Count));
132133

133134
Buffer.BlockCopy(read.Data, 0, buffer, offset * sizeof(float),
134135
count * sizeof(float));
135136

136137
var samples = count / 2;
137-
((EventEmitterOfT<double>) SamplesPlayed).Trigger(samples);
138+
((EventEmitterOfT<double>) SamplesPlayed).Trigger(samples / SynthConstants.AudioChannels);
138139

139140
RequestBuffers();
140141

src.kotlin/alphaTab/alphaTab/src/androidMain/kotlin/alphaTab/platform/android/AndroidAudioWorker.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ internal class AndroidAudioWorker(
4848
private fun writeSamples() {
4949
while (!_stopped) {
5050
if (_track.playState == AudioTrack.PLAYSTATE_PLAYING) {
51-
_output.read(_buffer, 0, _buffer.size)
51+
val samplesFromBuffer = _output.read(_buffer, 0, _buffer.size)
5252
if (_previousPosition == -1) {
5353
_previousPosition = _track.playbackHeadPosition
5454
_track.getTimestamp(_timestamp)
5555
}
56-
_track.write(_buffer, 0, _buffer.size, AudioTrack.WRITE_BLOCKING)
56+
_track.write(_buffer, 0, samplesFromBuffer, AudioTrack.WRITE_BLOCKING)
5757
} else {
5858
_playingSemaphore.acquire() // wait for playing to start
5959
_playingSemaphore.release() // release semaphore for others

src/AlphaTabApiBase.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ export class AlphaTabApiBase<TSettings> {
994994
if (
995995
nextBeatBoundings &&
996996
nextBeatBoundings.barBounds.masterBarBounds.staveGroupBounds ===
997-
barBoundings.staveGroupBounds
997+
barBoundings.staveGroupBounds
998998
) {
999999
nextBeatX = nextBeatBoundings.visualBounds.x;
10001000
}
@@ -1032,13 +1032,18 @@ export class AlphaTabApiBase<TSettings> {
10321032
}
10331033

10341034
private _beatMouseDown: boolean = false;
1035+
private _noteMouseDown: boolean = false;
10351036
private _selectionStart: SelectionInfo | null = null;
10361037
private _selectionEnd: SelectionInfo | null = null;
10371038

10381039
public beatMouseDown: IEventEmitterOfT<Beat> = new EventEmitterOfT<Beat>();
10391040
public beatMouseMove: IEventEmitterOfT<Beat> = new EventEmitterOfT<Beat>();
10401041
public beatMouseUp: IEventEmitterOfT<Beat | null> = new EventEmitterOfT<Beat | null>();
10411042

1043+
public noteMouseDown: IEventEmitterOfT<Note> = new EventEmitterOfT<Note>();
1044+
public noteMouseMove: IEventEmitterOfT<Note> = new EventEmitterOfT<Note>();
1045+
public noteMouseUp: IEventEmitterOfT<Note | null> = new EventEmitterOfT<Note | null>();
1046+
10421047
private onBeatMouseDown(originalEvent: IMouseEventArgs, beat: Beat): void {
10431048
if (this._isDestroyed) {
10441049
return;
@@ -1057,6 +1062,16 @@ export class AlphaTabApiBase<TSettings> {
10571062
this.uiFacade.triggerEvent(this.container, 'beatMouseDown', beat, originalEvent);
10581063
}
10591064

1065+
private onNoteMouseDown(originalEvent: IMouseEventArgs, note: Note): void {
1066+
if (this._isDestroyed) {
1067+
return;
1068+
}
1069+
1070+
this._noteMouseDown = true;
1071+
(this.noteMouseDown as EventEmitterOfT<Note>).trigger(note);
1072+
this.uiFacade.triggerEvent(this.container, 'noteMouseDown', note, originalEvent);
1073+
}
1074+
10601075
private onBeatMouseMove(originalEvent: IMouseEventArgs, beat: Beat): void {
10611076
if (this._isDestroyed) {
10621077
return;
@@ -1072,6 +1087,15 @@ export class AlphaTabApiBase<TSettings> {
10721087
this.uiFacade.triggerEvent(this.container, 'beatMouseMove', beat, originalEvent);
10731088
}
10741089

1090+
private onNoteMouseMove(originalEvent: IMouseEventArgs, note: Note): void {
1091+
if (this._isDestroyed) {
1092+
return;
1093+
}
1094+
1095+
(this.noteMouseMove as EventEmitterOfT<Note>).trigger(note);
1096+
this.uiFacade.triggerEvent(this.container, 'noteMouseMove', note, originalEvent);
1097+
}
1098+
10751099
private onBeatMouseUp(originalEvent: IMouseEventArgs, beat: Beat | null): void {
10761100
if (this._isDestroyed) {
10771101
return;
@@ -1127,6 +1151,17 @@ export class AlphaTabApiBase<TSettings> {
11271151
this._beatMouseDown = false;
11281152
}
11291153

1154+
1155+
private onNoteMouseUp(originalEvent: IMouseEventArgs, note: Note | null): void {
1156+
if (this._isDestroyed) {
1157+
return;
1158+
}
1159+
1160+
(this.noteMouseUp as EventEmitterOfT<Note | null>).trigger(note);
1161+
this.uiFacade.triggerEvent(this.container, 'noteMouseUp', note, originalEvent);
1162+
this._noteMouseDown = false;
1163+
}
1164+
11301165
private updateSelectionCursor(range: PlaybackRange | null) {
11311166
if (!this._tickCache) {
11321167
return;
@@ -1157,6 +1192,14 @@ export class AlphaTabApiBase<TSettings> {
11571192
let beat: Beat | null = this.renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
11581193
if (beat) {
11591194
this.onBeatMouseDown(e, beat);
1195+
1196+
if (this.settings.core.includeNoteBounds) {
1197+
const note = this.renderer.boundsLookup?.getNoteAtPos(beat, relX, relY);
1198+
if (note) {
1199+
this.onNoteMouseDown(e, note);
1200+
}
1201+
}
1202+
11601203
}
11611204
});
11621205
this.canvasElement.mouseMove.on(e => {
@@ -1168,6 +1211,13 @@ export class AlphaTabApiBase<TSettings> {
11681211
let beat: Beat | null = this.renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
11691212
if (beat) {
11701213
this.onBeatMouseMove(e, beat);
1214+
1215+
if (this._noteMouseDown) {
1216+
const note = this.renderer.boundsLookup?.getNoteAtPos(beat, relX, relY);
1217+
if (note) {
1218+
this.onNoteMouseMove(e, note);
1219+
}
1220+
}
11711221
}
11721222
});
11731223
this.canvasElement.mouseUp.on(e => {
@@ -1181,6 +1231,16 @@ export class AlphaTabApiBase<TSettings> {
11811231
let relY: number = e.getY(this.canvasElement);
11821232
let beat: Beat | null = this.renderer.boundsLookup?.getBeatAtPos(relX, relY) ?? null;
11831233
this.onBeatMouseUp(e, beat);
1234+
1235+
if (this._noteMouseDown) {
1236+
if (beat) {
1237+
const note = this.renderer.boundsLookup?.getNoteAtPos(beat, relX, relY) ?? null;
1238+
this.onNoteMouseUp(e, note);
1239+
}
1240+
else {
1241+
this.onNoteMouseUp(e, null);
1242+
}
1243+
}
11841244
});
11851245
this.renderer.postRenderFinished.on(() => {
11861246
if (

src/midi/MidiFileGenerator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,7 @@ export class MidiFileGenerator {
13621362
this.prepareSingleBeat(note.beat);
13631363
this.generateNote(
13641364
note,
1365-
-note.beat.playbackStart,
1365+
0,
13661366
note.beat.playbackDuration,
13671367
new Int32Array(note.beat.voice.bar.staff.tuning.length)
13681368
);

src/platform/javascript/AlphaSynthAudioWorkletOutput.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Environment } from '@src/Environment';
33
import { Logger } from '@src/Logger';
44
import { AlphaSynthWorkerSynthOutput } from '@src/platform/javascript/AlphaSynthWorkerSynthOutput';
55
import { AlphaSynthWebAudioOutputBase } from '@src/platform/javascript/AlphaSynthWebAudioOutputBase';
6+
import { SynthConstants } from '@src/synth/SynthConstants';
67

78
/**
89
* @target web
@@ -58,7 +59,7 @@ export class AlphaSynthWebWorklet {
5859
constructor(...args: any[]) {
5960
super(...args);
6061

61-
Logger.info('WebAudio', 'creating processor');
62+
Logger.debug('WebAudio', 'creating processor');
6263

6364
this._bufferCount = Math.floor(
6465
(AlphaSynthWebWorkletProcessor.TotalBufferTimeInMilliseconds *
@@ -110,15 +111,15 @@ export class AlphaSynthWebWorklet {
110111
buffer = new Float32Array(samples);
111112
this._outputBuffer = buffer;
112113
}
113-
this._circularBuffer.read(buffer, 0, Math.min(buffer.length, this._circularBuffer.count));
114+
const samplesFromBuffer = this._circularBuffer.read(buffer, 0, Math.min(buffer.length, this._circularBuffer.count));
114115
let s: number = 0;
115116
for (let i: number = 0; i < left.length; i++) {
116117
left[i] = buffer[s++];
117118
right[i] = buffer[s++];
118119
}
119120
this.port.postMessage({
120121
cmd: AlphaSynthWorkerSynthOutput.CmdOutputSamplesPlayed,
121-
samples: left.length
122+
samples: samplesFromBuffer / SynthConstants.AudioChannels
122123
});
123124
this.requestBuffers();
124125

src/platform/javascript/AlphaSynthScriptProcessorOutput.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CircularSampleBuffer } from '@src/synth/ds/CircularSampleBuffer';
22
import { AlphaSynthWebAudioOutputBase } from '@src/platform/javascript/AlphaSynthWebAudioOutputBase';
3+
import { SynthConstants } from '@src/synth/SynthConstants';
34

45
// tslint:disable: deprecation
56

@@ -86,13 +87,13 @@ export class AlphaSynthScriptProcessorOutput extends AlphaSynthWebAudioOutputBas
8687
buffer = new Float32Array(samples);
8788
this._outputBuffer = buffer;
8889
}
89-
this._circularBuffer.read(buffer, 0, Math.min(buffer.length, this._circularBuffer.count));
90+
const samplesFromBuffer = this._circularBuffer.read(buffer, 0, Math.min(buffer.length, this._circularBuffer.count));
9091
let s: number = 0;
9192
for (let i: number = 0; i < left.length; i++) {
9293
left[i] = buffer[s++];
9394
right[i] = buffer[s++];
9495
}
95-
this.onSamplesPlayed(left.length);
96+
this.onSamplesPlayed(samplesFromBuffer / SynthConstants.AudioChannels);
9697
this.requestBuffers();
9798
}
9899
}

src/platform/javascript/BrowserUiFacade.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,9 @@ export class BrowserUiFacade implements IUiFacade<unknown> {
472472
// remember which bar is contained in which node for faster lookup
473473
// on highlight/unhighlight
474474
for (let i = renderResult.firstMasterBarIndex; i <= renderResult.lastMasterBarIndex; i++) {
475-
this._barToElementLookup.set(i, placeholder);
475+
if(i >= 0) {
476+
this._barToElementLookup.set(i, placeholder);
477+
}
476478
}
477479

478480
if (this._api.settings.core.enableLazyLoading) {

src/rendering/RenderFinishedEventArgs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ export class RenderFinishedEventArgs {
4242
/**
4343
* Gets or sets the index of the first masterbar that was rendered in this result.
4444
*/
45-
public firstMasterBarIndex: number = 0;
45+
public firstMasterBarIndex: number = -1;
4646

4747
/**
4848
* Gets or sets the index of the last masterbar that was rendered in this result.
4949
*/
50-
public lastMasterBarIndex: number = 0;
50+
public lastMasterBarIndex: number = -1;
5151

5252
/**
5353
* Gets or sets the render engine specific result object which contains the rendered music sheet.

src/rendering/glyphs/NoteNumberGlyph.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,6 @@ export class NoteNumberGlyph extends Glyph {
112112
noteBounds.noteHeadBounds.y = cy + this.y - this.height/2;
113113
noteBounds.noteHeadBounds.w = this.width;
114114
noteBounds.noteHeadBounds.h = this.height;
115-
this.renderer.scoreRenderer.boundsLookup!.addNote(noteBounds);
115+
beatBounds.addNote(noteBounds);
116116
}
117117
}

src/rendering/layout/PageViewLayout.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ export class PageViewLayout extends ScoreLayout {
122122
e.height = tuningHeight;
123123
e.totalWidth = this.width;
124124
e.totalHeight = totalHeight < 0 ? y + e.height : totalHeight;
125-
e.firstMasterBarIndex = -1;
126-
e.lastMasterBarIndex = -1;
127125

128126
this.registerPartial(e, (canvas: ICanvas) => {
129127
canvas.color = res.scoreInfoColor;
@@ -151,8 +149,6 @@ export class PageViewLayout extends ScoreLayout {
151149
e.height = diagramHeight;
152150
e.totalWidth = this.width;
153151
e.totalHeight = totalHeight < 0 ? y + diagramHeight : totalHeight;
154-
e.firstMasterBarIndex = -1;
155-
e.lastMasterBarIndex = -1;
156152

157153
this.registerPartial(e, (canvas: ICanvas) => {
158154
canvas.color = res.scoreInfoColor;
@@ -218,8 +214,6 @@ export class PageViewLayout extends ScoreLayout {
218214
e.height = infoHeight;
219215
e.totalWidth = this.width;
220216
e.totalHeight = totalHeight < 0 ? y + e.height : totalHeight;
221-
e.firstMasterBarIndex = -1;
222-
e.lastMasterBarIndex = -1;
223217
this.registerPartial(e, (canvas: ICanvas) => {
224218
canvas.color = res.scoreInfoColor;
225219
canvas.textAlign = TextAlign.Center;

0 commit comments

Comments
 (0)