Code: Select all
if(... && track->patchCurrDeltaTime>=track->patchNextDeltaTime){
Code: Select all
if(... && track->patchCurrDeltaTime>=track->patchNextDeltaTime){
Code: Select all
diff --git a/kernel/uzeboxSoundEngine.c b/kernel/uzeboxSoundEngine.c
index 380c723..6913e5d 100644
--- a/kernel/uzeboxSoundEngine.c
+++ b/kernel/uzeboxSoundEngine.c
@@ -774,11 +774,10 @@ void ProcessMusic(void){
//process patch command stream
if((track->flags & TRACK_FLAGS_HOLD_ENV)==0){ //patchEnvelopeHold==false
- if(track->patchCommandStreamPos!=NULL &&
- track->patchCurrDeltaTime>=track->patchNextDeltaTime){
+ if(track->patchCommandStreamPos!=NULL){
//process all simultaneous events
- while(track->patchCurrDeltaTime==track->patchNextDeltaTime){
+ while(track->patchCurrDeltaTime>=track->patchNextDeltaTime){
c1=pgm_read_byte(track->patchCommandStreamPos++);
if(c1==0xff){
which makes me think that there is definitely another bug lurking somewhere in the sound code. Surprisingly, I also got a valid capture file from that run, which when played back will reliably crash uzem. The plot thickens…invalid insn 9188
Code: Select all
#define UZEMCHR _SFR_IO8(26) //uzem whisper port for outputting characters to the console
#define UZEMHEX _SFR_IO8(25) //uzem whisper port for outputting hex bytes values to the console
Code: Select all
UZEMCHR='2';
UZEMCHR='.';
UZEMHEX=(vsync_counter>>8);
UZEMHEX=(vsync_counter&0xff);
UZEMCHR=',';
UZEMHEX=triggerCount;
UZEMCHR=',';
UZEMHEX=trackNo;
UZEMCHR=',';
UZEMHEX=track->fxPatchNo;
UZEMCHR=',';
UZEMHEX=track->flags;
UZEMCHR=',';
UZEMHEX=(track->patchCurrDeltaTime);
UZEMCHR=',';
UZEMHEX=(track->patchNextDeltaTime);
UZEMCHR='\n';
Code: Select all
2.0a1e,48,02,00,10,01,01
1.0a3b,49,01,03,b0,00,00-01,00,00
2.0a40,49,01,03,10,01,01
1.0a41,4a,01,03,b0,00,00-01,00,00
2.0a44,4a,01,00,10,01,01
1.0a72,4b,01,00,b0,00,00-01,00,00
2.0a77,4b,01,03,10,01,01
1.0a8b,4c,01,03,b0,00,00-01,00,00
2.0a90,4c,01,02,10,01,01
1.0ab5,4d,01,02,b0,@0ab6@01,00-01,01,00
3.0ab7,4d,01,00,b0,01,00*
3.0ab8,4d,01,00,b0,02,00*
3.0ab9,4d,01,00,b0,03,00*
Code: Select all
track->flags|=TRACK_FLAGS_PLAYING;
Code: Select all
// Process patches command streams & final volume
//
for(unsigned char trackNo=0;trackNo<CHANNELS;trackNo++){
track=&tracks[trackNo];
//process patch command stream
if(track->flags & TRACK_FLAGS_PLAYING && (track->flags & TRACK_FLAGS_HOLD_ENV)==0){ //patchEnvelopeHold==false
if(track->patchCommandStreamPos!=NULL &&
track->patchCurrDeltaTime==track->patchNextDeltaTime){
Code: Select all
diff --git a/kernel/uzeboxSoundEngine.c b/kernel/uzeboxSoundEngine.c
index 380c723..6f4f89b 100644
--- a/kernel/uzeboxSoundEngine.c
+++ b/kernel/uzeboxSoundEngine.c
@@ -772,13 +772,12 @@ void ProcessMusic(void){
track=&tracks[trackNo];
//process patch command stream
- if((track->flags & TRACK_FLAGS_HOLD_ENV)==0){ //patchEnvelopeHold==false
+ if(track->flags & TRACK_FLAGS_PLAYING && (track->flags & TRACK_FLAGS_HOLD_ENV)==0){ //patchEnvelopeHold==false
- if(track->patchCommandStreamPos!=NULL &&
- track->patchCurrDeltaTime>=track->patchNextDeltaTime){
+ if(track->patchCommandStreamPos!=NULL){
//process all simultaneous events
- while(track->patchCurrDeltaTime==track->patchNextDeltaTime){
+ while(track->patchCurrDeltaTime>=track->patchNextDeltaTime){
c1=pgm_read_byte(track->patchCommandStreamPos++);
if(c1==0xff){
@@ -897,7 +896,6 @@ void TriggerCommon(u8 channel,u8 patch,u8 volume,u8 note){
track->envelopeVol=0xff;
track->noteVol=volume;
track->patchPlayingTime=0;
- track->flags|=TRACK_FLAGS_PLAYING;
track->flags&=(~(TRACK_FLAGS_HOLD_ENV|TRACK_FLAGS_SLIDING));
track->tremoloLevel=0;
track->tremoloPos=0;
@@ -979,6 +977,9 @@ void TriggerCommon(u8 channel,u8 patch,u8 volume,u8 note){
track->patchCommandStreamPos=pos;
}
+ //this memory barrier prevents the optimizing compiler from reordering the last statement in this function
+ __asm__ volatile ("" ::: "memory");
+ track->flags|=TRACK_FLAGS_PLAYING;
}
Code: Select all
track->flags|=TRACK_FLAGS_PLAYING;
Oh right, I forgot that when I've used memory barriers in the past that the variable I was protecting against reordering was volatile.uze6666 wrote:The memory barriers are interesting, didn't know about those. Though I read this article and it may not guarantee we won't have problems:
http://www.atmel.com/webdoc/AVRLibcRefe ... order.html
The real fix is probably to push the flag set at the end of the caller function. To be checked.
Code: Select all
tracks[channel].flags&=(~TRACK_FLAGS_PLAYING);
Good catch, I'll add this too. Same for TriggerNote().Artcfox wrote:It doesn't look like TriggerFx clears that flag before it steals a track, so I think we'll need to add:
right before the call to TriggerCommon.Code: Select all
tracks[channel].flags&=(~TRACK_FLAGS_PLAYING);