Skip to content

Commit 4367918

Browse files
committed
Finally fixed bugs in playback
1 parent df5d07b commit 4367918

2 files changed

Lines changed: 38 additions & 32 deletions

File tree

main.cpp

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#include <iostream>
2+
#include <chrono>
3+
24
#include <stdint-gcc.h>
35
#include <unistd.h>
46
#include <stdint.h>
5-
#include <chrono>
7+
68
#include <signal.h>
9+
#include <stdio.h>
710

811
#include "libusb/libusb.h"
912
#include "midifile/midifile.h"
@@ -13,7 +16,7 @@
1316
#define DEFAULT_INTERVAL_USEC 10000
1417

1518
#define DURATION_MAX -1
16-
#define NOTE_STOP 128
19+
#define NOTE_STOP -1
1720

1821
using namespace std;
1922

@@ -80,7 +83,7 @@ void SteamController_Close(SteamControllerInfos* controller){
8083
}
8184

8285

83-
int SteamController_PlayNote(SteamControllerInfos* controller, int haptic, unsigned int note,double duration = DURATION_MAX){
86+
int SteamController_PlayNote(SteamControllerInfos* controller, int haptic, int note,double duration = DURATION_MAX){
8487
double midiFrequency[128] = {8.1758, 8.66196, 9.17702, 9.72272, 10.3009, 10.9134, 11.5623, 12.2499, 12.9783, 13.75, 14.5676, 15.4339, 16.3516, 17.3239, 18.354, 19.4454, 20.6017, 21.8268, 23.1247, 24.4997, 25.9565, 27.5, 29.1352, 30.8677, 32.7032, 34.6478, 36.7081, 38.8909, 41.2034, 43.6535, 46.2493, 48.9994, 51.9131, 55, 58.2705, 61.7354, 65.4064, 69.2957, 73.4162, 77.7817, 82.4069, 87.3071, 92.4986, 97.9989, 103.826, 110, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880, 932.328, 987.767, 1046.5, 1108.73, 1174.66, 1244.51, 1318.51, 1396.91, 1479.98, 1567.98, 1661.22, 1760, 1864.66, 1975.53, 2093, 2217.46, 2349.32, 2489.02, 2637.02, 2793.83, 2959.96, 3135.96, 3322.44, 3520, 3729.31, 3951.07, 4186.01, 4434.92, 4698.64, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93, 6644.88, 7040, 7458.62, 7902.13, 8372.02, 8869.84, 9397.27, 9956.06, 10548.1, 11175.3, 11839.8, 12543.9};
8588

8689
unsigned char dataBlob[64] = {0x8f,
@@ -97,7 +100,7 @@ int SteamController_PlayNote(SteamControllerInfos* controller, int haptic, unsig
97100
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98101
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
99102

100-
if(note >= NOTE_STOP){
103+
if(note == NOTE_STOP){
101104
note = 0;
102105
duration = 0.0;
103106
}
@@ -136,17 +139,9 @@ float timeElapsedSince(std::chrono::steady_clock::time_point tOrigin){
136139
return time_span.count();
137140
}
138141

139-
bool isThisEventMaskingPreviousEvent(MidiFileEvent_t currentEvent, MidiFileEvent_t previousEvent){
140-
return (MidiFileEvent_isNoteEndEvent(currentEvent)
141-
&& MidiFileEvent_isNoteStartEvent(previousEvent)
142-
&& MidiFileNoteEndEvent_getChannel(currentEvent) == MidiFileNoteStartEvent_getChannel(previousEvent)
143-
&& MidiFileEvent_getTick(currentEvent) == MidiFileEvent_getTick(previousEvent));
144-
}
145-
146142

147-
148-
void displayCurrentNote(int channel, unsigned int note){
149-
static unsigned int notePerChannel[CHANNEL_COUNT] = {NOTE_STOP, NOTE_STOP};
143+
void displayPlayedNotes(int channel, int8_t note){
144+
static int8_t notePerChannel[CHANNEL_COUNT] = {NOTE_STOP, NOTE_STOP};
150145
const char* textPerChannel[CHANNEL_COUNT] = {"LEFT haptic : ",", RIGHT haptic : "};
151146
const char* noteBaseNameArray[12] = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
152147

@@ -159,7 +154,7 @@ void displayCurrentNote(int channel, unsigned int note){
159154
cout << textPerChannel[i];
160155

161156
//Write empty string
162-
if(notePerChannel[i] >= NOTE_STOP){
157+
if(notePerChannel[i] == NOTE_STOP){
163158
cout << "OFF";
164159
}
165160
else{
@@ -195,6 +190,9 @@ void playSong(SteamControllerInfos* controller,const ParamsStruct params){
195190
cout << "Starting playback of " <<params.midiSong << endl;
196191
sleep(1);
197192

193+
//This will contains the previous events accepted for each channel
194+
MidiFileEvent_t acceptedEventPerChannel[CHANNEL_COUNT] = {0};
195+
198196
//Get current time point, will be used to know elapsed time
199197
std::chrono::steady_clock::time_point tOrigin = std::chrono::steady_clock::now();
200198

@@ -203,49 +201,57 @@ void playSong(SteamControllerInfos* controller,const ParamsStruct params){
203201
while(currentEvent != NULL){
204202
usleep(params.intervalUSec);
205203

204+
//This will contains the events to play
205+
MidiFileEvent_t eventsToPlay[CHANNEL_COUNT] = {NULL};
206+
206207
//We now need to play all events with tick < currentTime
207208
long currentTick = MidiFile_getTickFromTime(midifile,timeElapsedSince(tOrigin));
208209

209-
//This will contain the events to send to the Steam Controller
210-
MidiFileEvent_t eventsToPlay[CHANNEL_COUNT] = {NULL};
211-
212-
//Iterate through all events until the current time
210+
//Iterate through all events until the current time, and selecte potential events to play
213211
for( ; currentEvent != NULL && MidiFileEvent_getTick(currentEvent) < currentTick ; currentEvent = MidiFileEvent_getNextEventInFile(currentEvent)){
214212

215-
//Only process Note events
216-
if (!MidiFileEvent_isNoteEvent(currentEvent)) continue;
213+
//Only process note start events or note end events matching previous event
214+
if (!MidiFileEvent_isNoteStartEvent(currentEvent) && !MidiFileEvent_isNoteEndEvent(currentEvent)) continue;
217215

218216
//Get channel event
219217
int eventChannel = MidiFileVoiceEvent_getChannel(currentEvent);
220218

221219
//If channel is other than 0 or 1, skip this event, we cannot play it with only 1 steam controller
222220
if(eventChannel < 0 || !(eventChannel < CHANNEL_COUNT)) continue;
223221

224-
//Check that this event is not masking another event
225-
//( this can happen when OFF and ON events share same timetick ,note and channel if OFF events arrives after ON event)
226-
if(isThisEventMaskingPreviousEvent(currentEvent, eventsToPlay[eventChannel])) continue;
222+
//If event is note off and does not match previous played event, skip it
223+
if(MidiFileEvent_isNoteEndEvent(currentEvent)){
224+
MidiFileEvent_t previousEvent = acceptedEventPerChannel[eventChannel];
227225

228-
//If we arrive here, this event match all conditions
229-
eventsToPlay[eventChannel]=currentEvent;
226+
//Skip if current event is not ending previous event,
227+
// or if they share the same tick ( end event after start evetn on same tick )
228+
if(MidiFileNoteStartEvent_getNote(previousEvent) != MidiFileNoteEndEvent_getNote(currentEvent)
229+
||(MidiFileEvent_getTick(currentEvent) == MidiFileEvent_getTick(previousEvent)))
230+
continue;
231+
}
232+
233+
//If we arrive here, this event is accepted
234+
eventsToPlay[eventChannel] = currentEvent;
235+
acceptedEventPerChannel[eventChannel]=currentEvent;
230236
}
231237

232238
//Now play the last events found
233239
for(int currentChannel = 0 ; currentChannel < CHANNEL_COUNT ; currentChannel++){
234240
MidiFileEvent_t selectedEvent = eventsToPlay[currentChannel];
235241

236242
//If no note event available on the channel, skip it
237-
if(selectedEvent == NULL && !MidiFileEvent_isNoteEvent(selectedEvent)) continue;
243+
if(!MidiFileEvent_isNoteEvent(selectedEvent)) continue;
238244

239245
//Set note event
240-
unsigned int eventNote = NOTE_STOP;
246+
int8_t eventNote = NOTE_STOP;
241247
if(MidiFileEvent_isNoteStartEvent(selectedEvent)){
242248
eventNote = MidiFileNoteStartEvent_getNote(selectedEvent);
243249
}
244250

251+
//Play notes
245252
SteamController_PlayNote(controller,currentChannel,eventNote);
246-
displayCurrentNote(currentChannel, eventNote);
253+
displayPlayedNotes(currentChannel,eventNote);
247254
}
248-
249255
}
250256

251257
cout <<endl<< "Playback completed " << endl;

midifile/midifile.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ static void add_event(MidiFileEvent_t new_event)
257257

258258
MidiFileEvent_t event;
259259

260-
for (event = new_event->track->last_event; (event != NULL) && (new_event->tick < event->tick); event = event->previous_event_in_track) {}
260+
for (event = new_event->track->last_event; (event != NULL) && (new_event->tick < event->tick); event = event->previous_event_in_track) {}
261261

262262
new_event->previous_event_in_track = event;
263263

@@ -281,7 +281,7 @@ static void add_event(MidiFileEvent_t new_event)
281281
new_event->next_event_in_track->previous_event_in_track = new_event;
282282
}
283283

284-
for (event = new_event->track->midi_file->last_event; (event != NULL) && (new_event->tick < event->tick); event = event->previous_event_in_file) {}
284+
for (event = new_event->track->midi_file->last_event; (event != NULL) && (new_event->tick < event->tick); event = event->previous_event_in_file) {}
285285

286286
new_event->previous_event_in_file = event;
287287

0 commit comments

Comments
 (0)