Skip to content

miscalculated Sound.duration() (non-standard sample rate) #6673

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

Open
ousia opened this issue Apr 10, 2022 · 16 comments
Open

miscalculated Sound.duration() (non-standard sample rate) #6673

ousia opened this issue Apr 10, 2022 · 16 comments
Labels
A-audio Area: Audio bug Something isn't working

Comments

@ousia
Copy link
Contributor

ousia commented Apr 10, 2022

The attached image shows how Flash Player and Ruffle display the Sound.duration() of the audio contained in https://www.free-culture.tk/lfc-presentation.swf:

dm-rfflvfp

As @Herschel has explained many times, the problem here is that the sound file has a non-standard sample rate 16kHz (although it is tagged in the SWF animation as being 11kHz).

For both Sound.position() and Sound.duration(), sample rate should be read from theMP3 file itself (not from SWF tagging).

BTW, I think there is no need to attach a sample file (it’s over 5MB). Let me know, if you need it.

Many thanks for your excellent work.

@ousia
Copy link
Contributor Author

ousia commented Aug 2, 2022

Even after #4273, miscalculated Sound.duration() is still there.

@ousia
Copy link
Contributor Author

ousia commented Aug 2, 2022

Although tagged as MP3 11Khz 16Bit mono in the SWF file, the actual sample rate is 16kHz.

@n0samu
Copy link
Member

n0samu commented Aug 6, 2022

As a workaround, why not modify the SWF file so the sound sample rate is tagged correctly?

@ousia
Copy link
Contributor Author

ousia commented Aug 7, 2022

As a workaround, why not modify the SWF file so the sound sample rate is tagged correctly?

Many thanks for your reply, @n0samu.

Well, in that case I’d have to modify the MP3 file itself. According to the SWF File Format Specification:

The sampling rate. This is ignored for Nellymoser and Speex codecs. 5.5kHz is not allowed for MP3. 0 = 5.5 kHz; 1 = 11 kHz; 2 = 22 kHz; 3 = 44 kHz.

In theory, 16kHz would be an invalid value. But in practice, the official player from Adobe had no problem with it.

If Sound.position() works right with this value for sampling rate, I think it would be consistent to make it work right with Sound.duration().

Many thanks for your help.

@n0samu
Copy link
Member

n0samu commented Aug 8, 2022

Ah that makes sense, I agree with what you're saying then

@ousia
Copy link
Contributor Author

ousia commented Aug 10, 2022

@n0samu,

I think this may be an easy fix, but I’m afraid I cannot code (in almost any programing language known to humankind 😅).

So, I will have to wait for the fix.

@ousia
Copy link
Contributor Author

ousia commented Dec 19, 2022

BTW, this prevents having a timer with total time in sound.

@n0samu n0samu added bug Something isn't working A-audio Area: Audio labels Dec 20, 2022
@ousia
Copy link
Contributor Author

ousia commented Dec 24, 2022

This is what I meant in my previous comment:

wrong-timer-fs8

Total playing time is wrong, see bellow:

right-timer-fs8

Buttons are also missing in Ruffle, because of indirect reference (#5492).

Many thanks for your help and happy holidays.

@ousia
Copy link
Contributor Author

ousia commented Feb 14, 2023

Just in case this might help to fix this issue.

In 3dfa5ad, @Herschel fixed distorted playing in MP3 with non-standard sample rates.

The sample rate is read from MP3 itself for Sound.position(), but from the tag in SWF for Sound.duration().

This might be where it is defined

let sample_rate: f64 = sound.format.sample_rate.into();

I wonder whether it should be something similar to:

let sample_rate: f64 = sound.decoder.sample_rate.into();

Of course, this is probably wrong, since all of this is totally Greek to me.

But I wonder whether this might help to advance a PR to fix Sound.duration() for non-standard frame rates.

Many thanks for your help.

@n0samu
Copy link
Member

n0samu commented Feb 15, 2023

As far as I can tell, there is no change that simple that could fix this problem. audio.rs is dealing only with reading the SWF tags and is treating the actual MP3 data as opaque. Meanwhile the MP3 decoder is feeding the MP3 data into Symphonia frame by frame. I think Ruffle throws away all of the MP3 metadata and it would be a fair bit of work to get it reading that metadata just to correctly handle this type of corner case.

Oh, and the reason why Sound.position() is working correctly is because keeping track of that is necessary to correctly play the sound at all. Keeping track of this value does not require reading the MP3 metadata.

And regarding the commit from Herschel that you linked, it's true that Ruffle's audio decoder now uses the correct sample rate, but reporting it to ActionScript is a different matter entirely. The ActionScript values are set when the SWF tag is read, not when the sound is streamed.

None of this means that the task is impossible or even very difficult, but it's not as simple as it sounds.

@ousia
Copy link
Contributor Author

ousia commented Feb 17, 2023

@n0samu, many thanks for your explanation.

Oh, and the reason why Sound.position() is working correctly is because keeping track of that is necessary to correctly play the sound at all. Keeping track of this value does not require reading the MP3 metadata.

I thought the same logic could be applied to Sound.duration() (not reading the MP3 metadata in SWF to provide the value).

Many thanks for your help again.

@Klymins
Copy link

Klymins commented Oct 26, 2024

Out of topic but I can't use a 16kHz MP3 stream in a Flash file (it simply doesn't play on the original Flash Player), can you tell me how can you do that while keeping the original Flash Player able to play it @ousia ?

@ousia
Copy link
Contributor Author

ousia commented Oct 27, 2024

@Klymins,

swfc from SWFTools does that. Attached animation (remove the extra .txt extension) plays fine with Adobe Flash Player.

Be warned that sound quality is not great. I only reported this issue to be able to handle already generated animations.

Are you interested in fixing the issue? Many thanks for your help.

@Klymins
Copy link

Klymins commented Oct 27, 2024

Thanks @ousia , I don't have enough knowledge to solve this problem.

I could not run SWFC but I detected that the original Flash Player can't play 16kbps 16kHz MP3's those encoded by MP3Enc. Do you know why the original Flash Player is unable to play 16kbps 16kHz MP3's those encoded by MP3Enc (it's the MP3 encoder that is included in the original SWF creating programs)?

By the way, I did not detect any degrade on the sound quality, what do you mean by "sound quality is not great"?

@ousia
Copy link
Contributor Author

ousia commented Oct 27, 2024

@Klymins,

I use lame -m m -b 16 sound.wav to generate sound.mp3.

A binary for Win64 may be obtained from https://www.rarewares.org/mp3-lame-bundle.php.

Depending in your actual recorded sound, 16kbps may be too low quality.

I hope it helps.

@Klymins
Copy link

Klymins commented Oct 27, 2024

I thought you were talking about the quality of playing 16kHz content at 11025Hz, I understand now. But 16kbps is actually pretty standard in Flash (many Flash movies use it) and I think it's pretty good when it's encoded by MP3Enc at 11025Hz, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-audio Area: Audio bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants