Streams with non-constant sampling

Forums:

There are radio streams with sampling frequency being switched from time to time: 44.1 -> 48 -> 44.1 and so on. I guess they are not doing resampling and tracks are playing as they are. MOC can not handle these right. After the moment change happened MOC is continuing to play stream with wrong pitch/speed.

I seem to recall seeing a comment in the code somewhere about this... but where? I might be more motivated to go looking if you'd replied to my e-mails to you following similar investigations of your previous problem reports.

I see only one e-mail. Were there more of them?

This was another one.

Don't take it personally; you're not the only one. But it is a significant resource-hogger when we put effort into helping people only to have it stall for want of a response. I'm sure you can appreciate that.

Thank you for the https link.

I found the comment I was looking for, but it was actually for changed bit rate not changed sample rate.

Implementing this is not really feasible at present because the changes involved would be quite pervasive. However, it would be possible after changes I had already thought about but postponed indefinitely for the same reasons.

So, unless I have a flash of inspiration (which does happen), the handling of changing sample rates is not going to happen any time soon (if at all).

Sorry 'bout that, Chief.

Forgot to mention here that as a workaround for this problem I disabled libaac decoder plugin so ffmpeg plugin can be used instead. FFMpeg handles these nasty streams pretty well.

It looks like it's handled within the FFmpeg libraries. I'll do some digging and see if I can find where. It may be possible to do something similar within the AAC decoder, but it could be a bit of an effort.

Given that using the FFmpeg decoder instead is a viable workaround, is it worth investing that effort? There are an awful lot of other things still need doing.

Looking at man libfaad I found this:

NeAACDecDecode void* NEAACAPI NeAACDecDecode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo, unsigned char *buffer, unsigned long buffer_size); Decodes the AAC data passed in buffer. Returns a pointer to a sample buffer or NULL. Info about the decoded frame is filled in in the NeAACDecFrameInfo structure. This structure holds information about errors during decoding, number of sample, number of channels and samplerate. The returned buffer contains the channel interleaved samples of the frame.

So there's no other way around except reading and updating samplerate info with every decoded frame. And yeah, FFMpeg does this internally.

from aac.c:

static int decode_one_frame (struct aac_data *data, void *buffer, int count) { ... if (frame_info.channels != (unsigned char)data->channels || frame_info.samplerate != (unsigned long)data->sample_rate) { decoder_error (&data->error, ERROR_STREAM, 0, "%s", "Invalid channel or sample_rate count"); return -2; }

I'm really interested why this error is not happening (or is it?).
It means that frame_info.samplerate remains constant.
If so, this should be reported to https://github.com/knik0/faad2 I guess.

Maybe you have the ShowStreamErrors configuration option still defaulted to 'no'.

I had a quick look at how sample rate changing might be implemented (at least for AAC) and it appeared much easier than I had initially thought, but it was too late in the evening to engage in further dialogue (or coding). I shall look into it further today if I can find the time.

A patch is on its way to you now by e-mail. Let me know if you don't receive it or the result if you do.

Result is negative. Frequency doesn't change. Bahaviour is exactly the same as if there were no patch. But I think it's FAAD to blame here.

After some investigation, I can report that the sample rate in the NeAACDecFrameInfo structure (and, in fact, the entire structure) is cleared and reassigned from NeAACDecStruct.sf_index each time a new block is decoded. That field is intialised in NeAACDecInit() (i.e., when the audio stream is first opened).

Whether or not this field gets updated depends on the exact structure of the audio stream, but I'd not be surprised if it does not get updated again during the life of the stream.

At the start of one function (program_config_element()) there is an ominous comment which suggests it will not be and is not required to be:

An MPEG-4 Audio decoder is only required to follow the Program Configuration Element in GASpecificConfig(). The decoder shall ignore any Program Configuration Elements that may occur in raw data blocks. PCEs transmitted in raw data blocks cannot be used to convey decoder configuration information.

but I don't know enough about the AAC stream's data flow to know for sure. I'm assuming that a sample rate change is signalled in the "Program Configuration Element".

I'd suggest at this stage that you should direct a query upstream to the FAAD2 library developers as you suggested above.

Note: FFmpeg uses its own decoder (not the FAAD2 library) and I have not delved into it as any remedy is most likely to be found in the FAAD2 library and not within MOC.