Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

positionMillis() time units are not milliseconds #16

Open
thecomfychair2 opened this issue Nov 8, 2021 · 5 comments
Open

positionMillis() time units are not milliseconds #16

thecomfychair2 opened this issue Nov 8, 2021 · 5 comments
Labels

Comments

@thecomfychair2
Copy link

Firstly, this is a fantastic library and has worked straight out of the box to play AAC and MP3 files for my SD audio projects!

Delving a little deeper though, I'm trying to use the positionMillis() function to get the elapsed time of a playing track on a Teensy 4.1 using Arduino 1.8.16 and Teensyduino 1.55. In the standard Teensy Audio library, this is returns the elapsed time in milliseconds, however for the play_sd_aac library the value appears to be ~1950x greater than expected. What unit of time should be returned by positionMillis()?

This is a short example comparing the normal Arduino millis() and position.Millis(). The file did not start playing at millis() == 0, but this demonstrates the discrepancy in relative change between the two values:

millis() positionMillis()
16843 19694706
16853 19717286
16863 19734220
16873 19751154
16883 19773734
16893 19790668
16903 19813248
16913 19830182
16923 19852760
16933 19869696
16943 19892274
16953 19909208
16963 19931788
16973 19948722
16983 19965656
16993 19988236
17003 20005170
17013 20027750
17023 20044684
17033 20067264
17043 20084198
17054 20106776
17064 20123712
17074 20146290
17084 20163224
17094 20180160
17104 20202738
17114 20219672
17124 20242252
17134 20259186
17144 20281766
17154 20298700
17164 20321280
17174 20338214
17184 20355148
17194 20377728
17204 20394662
17214 20417240

These values were generated as part of a larger project thus:
songPos = playAac1.positionMillis()
Serial.print(millis());
Serial.print("...");
Serial.print(songPos);
Serial.print("...");

If need be, I can knock up a full test to replicate the issue.

@FrankBoesing
Copy link
Owner

Yes, this is a known problem. Does not seem very important, the last few years no one missed this :)
I recently switched to an other MCU, and I don't know when I'll get around to taking care of it next. Might take longer...
Workaround: measure the time yourself with millis()

I know this is not a satisfying answer :)
As I don't know when, and If I fix this, I mark this as "wontfix".

@thecomfychair2
Copy link
Author

I understand, even after a cursory glance at the structure of AAC and MP3, getting even a roughly accurate duration or seek position value looks like quite a task!
Unfortunately using millis() won't cover all my use cases, as I would eventually like to be able to skip backwards and forwards within an audio file while it's playing so an actual position from the file itself would be needed. This may turn out to be impossible, but worth a shot.
What is positionMillis() returning now then? Since it seems to be a value that increases semi-consistently with time, I'm tempted to see if some sort of elapsed time can be calculated from it.

@pr8x
Copy link

pr8x commented Apr 18, 2023

just stumbled opon the same issue. This works for me:

unsigned positionMillis(void) { return (samples_played / AUDIO_SAMPLE_RATE_EXACT) * 1000;}

(Sample rate is samples per second, so we need to check how many seconds we already played and multiply with 1000 to convert to milliseconds)

@pr8x
Copy link

pr8x commented Apr 18, 2023

lengthMillis (for mp3) is completely wrong though (I think). It's not easily possible to determine the length of mp3s by just looking at the byte offset - even with CBR. I think the correct way would be to count frames, but that would require reading the whole file first. Might be better to just chek ID3 tags instead.

@Ghostfighter6
Copy link

Ghostfighter6 commented Dec 17, 2023

I observed the same issue in positionMillis() ... see also https://forum.pjrc.com/index.php?threads/frankbs-arduino-teensy-codec-lib-playing-mp3.73819/
Additionally the data type of bitrate has to be unsigned long.

lengthMillis() is definitely wrong because of possibly changing bitrate from one audio frame to the next.
Since there is sometimes a Xing or Lame header introducing the audio frame with very low bitrates - which will lead to long audio playtime calculations because of the max() in lengthMillis() - the calculation of lengthMillis is much to long then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants