Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 03:42 11 Nov 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMX: String corruption after PLAY FLAC

Author Message
BrantB
Newbie

Joined: 27/10/2017
Location: Canada
Posts: 40
Posted: 08:14pm 08 Mar 2018
Copy link to clipboard 
Print this post

I promise, with Scout's honour, that I am not spending hours and hours specifically looking for problems . I certainly get no joy out of finding what appears to be a bug - though I am quite happy to "do my bit" and contribute in whatever way I can to the advancement of Micromite.

What I have been doing over the last several days, is exercising the elements of MMX that are of particular interest to me, because I know they will be needed in the projects I tend to get involved with. I first experiment with each of these elements in isolation (using simple scenarios for initial learning), and then I typically move them into an ever-growing piece of proof-of-concept code, which brings them all together.

As a result of my experiments, I am pretty sure I have stumbled over a problem with the PLAY FLAC routine. The playing itself works flawlessly - but, I think the internal 'wrap up' routine somehow stomps on string memory (regardless of whether or not the 'finished playing' interrupt is employed).

This did not show up in my initial, simple, isolated experiments - because all I did was play one file, and that was it. But then, when I merged the feature into my ever-growing proof-of-concept code, strange things started to happen (including routinely getting a CPU exception, resulting in reboots).

So I set about isolating the cause, and the code below is the result of trying to chase down what was happening. It has some constants which control the exact nature of the logic flow. This is because, during debugging, I pursued a few hypotheses.

First, I thought the issue had to do with the use of the 'finished playing' interrupt. Not so.

Then, it started to look like the problem might have been occurring (quite strangely) in a SELECT-CASE statement. Not so.

Eventually, I narrowed it down to just the actual playing of the FLAC file. As I said, the playing itself works fine. The problem only appears as the track is ending; that's when string memory pointers appear to go walkabout. From what I can tell, numeric variables seem to remain unaffected - but I would not want to swear that will always be the case.


OPTION EXPLICIT


' Change these constants to control how the program actually runs.
'
' USE_FLAC_DONE:
'
' 0 = Automatically advance the FLAC track every 90 seconds
' 1 = Use the FLAC "done" interrupt to advance the track
'
' USE_SELECT_CASE:
'
' 0 = Use a series of IF-THEN statements to assign FLAC filename
' 1 = Use a SELECT CASE block to assign FLAC filename
'
' ACTUALLY_PLAY:
'
' 0 = Skip the PLAY FLAC command
' (really only useful when USE_FLAC_DONE = 0
' 1 = Issue the PLAY FLAC command


CONST USE_FLAC_DONE = 0
CONST USE_SELECT_CASE = 1
CONST ACTUALLY_PLAY = 1


' Delare all variables appropriately

DIM TSEC AS INTEGER
DIM TFLAC AS INTEGER

DIM FLAC_PLAYING AS INTEGER
DIM FLAC_TRACK AS INTEGER
DIM FLAC_FILE$ AS STRING
DIM TEST_STRING$ AS STRING

DIM SHOW_DEBUG AS INTEGER


' Reset the Console printing interval to 0 (zero)

TSEC = 0
TFLAC = 0


' Reset the FLAC playlist variables

FLAC_PLAYING = 0
FLAC_TRACK = 0


' Reset the extra debugging flag

SHOW_DEBUG = 0


' Reset the TIMER to 0 (zero), and wait for a bit to gurantee
' that it will be >0 when the main loop starts

TIMER = 0
PAUSE 5


' --- MAIN LOOP ---

DO


' If the TIMER goes past the pre-determined printing interval,
' then print its current value to the Console, and calcualte
' the next trigger value (i.e. 5 seconds hence)

IF Timer > TSEC THEN
TSEC = TIMER + 5000
PRINT "TIMER: "; STR$(TIMER)
PRINT "TRACK: "; STR$(FLAC_TRACK)
PRINT "FILE: "; FLAC_FILE$
PRINT "TEST: "; TEST_STRING$
PRINT
END IF


' If we're in timed track mode (rather than using the DONE interrupt),
' then we have some work to do here

if USE_FLAC_DONE = 0 THEN

' If the TIMER goes past the pre-determined track interval,
' then reset the playing flag (to force a track change), and
' calculate the next trigger value (i.e., 90 seconds hence)

IF TIMER > TFLAC THEN
'Only show the debug info at the Track 1 -> Track 2 transition
IF (TFLAC > 80000) AND (TFLAC < 100000) THEN
SHOW_DEBUG = 1
END IF
TFLAC = TIMER + 90000
FLAC_PLAYING = 0
END IF

END IF


' Only process the FLAC playlist if nothing is currently playing

IF FLAC_PLAYING = 0 THEN

' Print some debug info to show how key variables behave

IF SHOW_DEBUG = 1 THEN
PRINT " DEBUG 1 - TRACK: "; STR$(FLAC_TRACK)
PRINT " DEBUG 1 - FILE: "; FLAC_FILE$
PRINT " DEBUG 1 - TEST: "; TEST_STRING$
END IF


' Advance the track number; wrap it around to 1 at the end

FLAC_TRACK = FLAC_TRACK + 1
IF FLAC_TRACK > 2 THEN
FLAC_TRACK = 1
END IF


' Print some debug info to show how key variables behave

IF SHOW_DEBUG = 1 THEN
PRINT " DEBUG 2 - TRACK: "; STR$(FLAC_TRACK)
PRINT " DEBUG 2 - FILE: "; FLAC_FILE$
PRINT " DEBUG 2 - TEST: "; TEST_STRING$
END IF


' Based on the track number, assign an actual filename to play
'
' NOTE: The exact method used to traslate the track number
' into a filename, depends on how one of our constants is set.
' We will either use (the nicer) SELECT-CASE method, or instead,
' use a series of IF-THEN's.

IF USE_SELECT_CASE = 1 THEN

SELECT CASE FLAC_TRACK

CASE 1

FLAC_FILE$ = "\111.FLAC"
TEST_STRING$ = "TRACK ONE"

CASE 2

FLAC_FILE$ = "\125.FLAC"
TEST_STRING$ = "TRACK TWO"

CASE ELSE

FLAC_FILE$ = ""
TEST STRING = "NO TRACK"

END SELECT

ELSE

FLAC_FILE$ = ""
TEST_STRING$ = "NO TRACK"

IF FLAC_TRACK = 1 THEN
FLAC_FILE$ = "\111.FLAC"
TEST_STRING$ = "TRACK ONE"
END IF

IF FLAC_TRACK = 2 THEN
FLAC_FILE$ = "\125.FLAC"
TEST_STRING$ = "TRACK TWO"
END IF

END IF


' Print some debug info to show how key variables behave

IF SHOW_DEBUG = 1 THEN
PRINT " DEBUG 3 - TRACK: "; STR$(FLAC_TRACK)
PRINT " DEBUG 3 - FILE: "; FLAC_FILE$
PRINT " DEBUG 3 - TEST: "; TEST_STRING$
END IF


' Only process the filename if it is valid

IF FLAC_FILE$ <> "" THEN

' Set the flag to indicate that we're busy playing tunes

FLAC_PLAYING = 1

' Play the file (either with, or with the interrupt feature,
' depending on the mode selected by our constants).

if USE_FLAC_DONE = 1 THEN

' Only issue the PLAY command, if our constants tell us to

IF ACTUALLY_PLAY = 1 THEN
PLAY FLAC FLAC_FILE$, INT_FLAC_DONE
END IF

ELSE

' Only issue the PLAY command, if our constants tell us to

IF ACTUALLY_PLAY = 1 THEN
PLAY FLAC FLAC_FILE$
END IF

END IF

' Print to the Console, the name of what we are playing

PRINT "Playing: ";FLAC_FILE$

END IF

' Print some debug info to show how key variables behave

IF SHOW_DEBUG = 1 THEN
PRINT " DEBUG 4 - TRACK: "; STR$(FLAC_TRACK)
PRINT " DEBUG 4 - FILE: "; FLAC_FILE$
PRINT " DEBUG 4 - TEST: "; TEST_STRING$
SHOW_DEBUG = 0
END IF

end if


' Automatically quit after 5 minutes (300,000ms)

LOOP UNTIL TIMER > 300000


' --- END of MAIN LOOP ---


' Ensure current track is stopped (no harm if it already is)

PLAY STOP


' INTERRUPT - Triggers when FLAC playback is complete

SUB INT_FLAC_DONE


' Update the flag to show that we are no longer busy

FLAC_PLAYING = 0

SHOW_DEBUG = 1

' Give a nod to the Console

PRINT "FLAC DONE!"


END SUB



END




I was originally going to attach a ZIP containing the two FLAC files that I used for experimenting (just in case it has something do to with the specific data stream - though, unlikely), as well as some debug output - but the ZIP (at 17MB) was going to exceed size limits for the forum.

2018-03-09_061330_FLAC_Debug_Output.zip

So, I have only ZIPped the debug output (no FLAC files) for the following two scenarios:


CONST USE_FLAC_DONE = 0
CONST USE_SELECT_CASE = 1
CONST ACTUALLY_PLAY = 0


... and:


CONST USE_FLAC_DONE = 0
CONST USE_SELECT_CASE = 1
CONST ACTUALLY_PLAY = 1


In the two lots of debug output, I have manually added the text *****TRANSITION***** where ever the program/output should be moving from one FLAC track to another. This will allow anyone investigating/duplicating this to quickly jump to the more "interesting" sections of the output - in order to see/verify results.

In the case where the PLAY command is actually used, pay particular attention to the first *****TRANSITION***** event (from track 1 to 2). Note how, just before the ending of the first track, the debug info shows as follows:


TIMER: 85163
TRACK: 1
FILE: \111.FLAC
TEST: TRACK ONE


... but after the 1st track has ended, and the code has tried to update the variables to play the 2nd track, the debug info shows as follows:


TIMER: 90164
TRACK: 1
FILE: FILE:
TEST: LAC_TRACK


Note the info highlighted in red. That's a problem; nothing in the code assigns those values. (Those look more like string constants and/or parts of variable names.) The FILE: item should show as \125.FLAC, and the TEST: item should show as TRACK TWO.


I suspect this is something that @matherp will need to look at.

CPU: PIC32MZ2048EFH100 (200Mhz)
MMX: v5.0414

Cheers,

Brant
Edited by BrantB 2018-03-10
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10569
Posted: 11:05pm 08 Mar 2018
Copy link to clipboard 
Print this post

Does the same thing happen playing WAV files? On the MMX and the MM+?
 
BrantB
Newbie

Joined: 27/10/2017
Location: Canada
Posts: 40
Posted: 11:44pm 08 Mar 2018
Copy link to clipboard 
Print this post

Ah, I cannot answer that at this point. I don't have an MM+ environment to test on, and have not yet rigged up my MMX environment to hear WAV playback.

That latter point brings me to another question, though. In the most recent version of the MMX manual, pin 6 (for 100pin CPU) is shown as PWM-2C and SOUND-LEFT. I can accept that (although, I would have expected it on 2A). But SOUND-RIGHT is shown on pin 18 - and that pin does not appear to have a PWM facility. PWM-2B is shown on pin 40.

So ... my question is ... what is the correct way to wire things up for WAV playback on a 100pin MMX? Armed with that, I should be able to at least provide you with an answer to that unknown.

(Unfortunately, physical re-wiring will now have to wait until tomorrow, as I have to head home for a hot meal - lest I disrupt domestic harmony .)
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10569
Posted: 07:53am 09 Mar 2018
Copy link to clipboard 
Print this post

  Quote  what is the correct way to wire things up for WAV playback on a 100pin MMX?


As per the manual - sound is not related to PWM except that in the 100-pin I ran out of unallocated pins that were capable of the function. If you look at the 144-pin sound and PWM pin usage don't overlap.

It is set to PWM2C so you can still use 1A and 1B for normal PWMEdited by matherp 2018-03-10
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10569
Posted: 11:10am 09 Mar 2018
Copy link to clipboard 
Print this post

Please try the attached - seems to fix it for me (not sure why though )

2018-03-09_212459_MMX5.04.14.zip Edited by matherp 2018-03-10
 
BrantB
Newbie

Joined: 27/10/2017
Location: Canada
Posts: 40
Posted: 05:34pm 09 Mar 2018
Copy link to clipboard 
Print this post

  Quote  
Please try the attached - seems to fix it for me (not sure why though )


I tried your update (I was VERY careful to make sure I was flashing the correct firmware this time, so as to ensure that I avoided that embarrassment again ), and it seems to have fixed it for me too .

I exercised various combinations of its use (i.e., with and without the 'done' interrupt, etc.) in the isolated test program, and all results were good. I then also tried it in my ever-growing proof-of-concept program, and it performed well in that scenario too.

Many thanks for the quick fix. (And if you are not sure why this works, a mere mortal like me stands no chance whatsoever !)

  Quote  
As per the manual - sound is not related to PWM except that in the 100-pin I ran out of unallocated pins that were capable of the function. If you look at the 144-pin sound and PWM pin usage don't overlap.


I would like to be very careful with regards to how I go about pursing my next inquiry. I am very sensitive to the fact that I am still a newbie around here, and I assure you there is no complaint, challenge, or any other such negative connotation intended here. (Ah, the disadvantages of the written word, as opposed to a live conversation.)

What did I miss? Where/How could I have determined for myself that WAV playback is not related to PWM (other than the happenstance of pin allocation)?

I certainly don't want to be asking questions for which there are already published answers ... and the last thing I want to do is give the impression that I don't put any effort into reading through the manuals (and/or other threads) before posting in the forum. I am definitely not "that" guy (every forum has one ... or more).

But, to be brutally honest (without any offence intended), following the manuals can be a little bit confusing at times.

I have the impression that the Plus manual only covers whatever is not already covered in the "standard" manual, and that the eXtreme manual only covers what is not already covered in the other two, combined. Is that a fair assessment? (If not, I need to know - so I don't perpetuate my confusion .)

Using that approach, I reviewed the Plus manual to learn about WAV playback - and there, it talks about PWM channel 2, the 80KHz carrier frequency, low pass filter, implications to the SERVO command, etc. Nothing in the eXtreme manual seemed to suggest that the methodology was any different in MMX. So, I was left with the distinct impression that the WAV playback was dependent upon the PWM signals.

Did I somehow totally misinterpret the manual(s)? If so, my apologies.

BTW - I have some other things to exercise today, with my MMX rig remaining wired as it currently is. However, over the weekend, I will adjust it for WAV playback (as per the MMX manual) and test/confirm that aspect of your update as well. (And, of course, I will report back to this thread.)

Again, many thanks for the fix (and for all that you do).

Cheers!
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10569
Posted: 06:06pm 09 Mar 2018
Copy link to clipboard 
Print this post

  Quote  What did I miss? Where/How could I have determined for myself that WAV playback is not related to PWM (other than the happenstance of pin allocation)?


There was no intention to be pejorative in my reply, I was just pointing out that the pin allocation in the manual was correct.

The long answer is much more complex

PWM and sound both make use of the output compare function in the PIC. Only certain pins are capable of this and moreover for each pin that is there is only one or two timers that can be used to clock it.

The PIC32MZ has slightly more flexibility than the PIC32MX. So on the 144-pin I can have 3 output compare channels on each of two clocks and still have a timer and two channels available for sound.
On the 100-pin I've got the three timers but have run out of pins to have 8 individual output compare channels. The pin used for PWM-2C can use either the sound clock or the PWM2 clock. If you use sound it is allocated to that clock and if you use it for PWM it is allocated to the PWM clock. This can only really be fully understood by reading the PIC manual so MMBasic tries to hide that sort of detail.

The manuals do build up as you say and it does make it somewhat difficult but other than any missed errors in the manuals if a pin is allocated to a particular function then it can be used for that function and will only interact with other defined uses of that specific pin unless specifically documented

Don't know if this helps - confuses me just writing itEdited by matherp 2018-03-11
 
BrantB
Newbie

Joined: 27/10/2017
Location: Canada
Posts: 40
Posted: 07:09pm 09 Mar 2018
Copy link to clipboard 
Print this post

  Quote  
The long answer is much more complex
.
.
so MMBasic tries to hide that sort of detail.
.
.
Don't know if this helps - confuses me just writing it


Well, why didn't you just say so in the first place ... we could have avoided all of that.

Okay, seriously ... I do appreciate your explanation. I have a character flaw for which I blame (er, uh, credit) my parents - "knowing" something is all well and good, but understanding it is even better.

Now that I have a bit better understanding of the WAV/(non-)PWM circumstances, it makes much more sense to me. (And I didn't read any snark into your initial response ... I just wondered how I had managed to miss the mark so terribly . All good.)
 
BrantB
Newbie

Joined: 27/10/2017
Location: Canada
Posts: 40
Posted: 09:13pm 10 Mar 2018
Copy link to clipboard 
Print this post

For the sake of completeness (and to follow through on the promise I made), I have now tested the behaviour of the WAV playback - both in the earlier firmware (in which the FLAC playback issue was first discovered), and in the most recent version (in which it was fixed).

Last things first - WAV playback works just fine in the latest/fixed firmware.

Interestingly, though, it turns out that the WAV playback also works (worked) just fine in the older firmware too. In other words, the WAV playback apparently never did cause any string corruption. Hmm.

@matherp - I know you mentioned you weren't quite sure why your fix works ... but, are these results consistent with whatever you changed? Or does this now make the issue even more confusing?
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025