Bug 5107 - AudioFileStream.FrameToPacket() returns bad data
Summary: AudioFileStream.FrameToPacket() returns bad data
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 5.2
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2012-05-15 21:10 UTC by adam.lickel
Modified: 2012-06-01 07:53 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description adam.lickel 2012-05-15 21:10:13 UTC
For seeking, we are using the following logic:
* Guess the frame
* Convert that to a packet
* Call AudioFileStream.Seek() to find the byte offset

In MonoTouch, this doesn't work. The packet returned is inaccurate and seemingly random. Using StreamBasicDescription.FramesPerPacket, I can calculate the packet consistently.

This seems like a MonoTouch binding bug.

--- [AudioConverter] AudioFileStream.FrameToPacket()
51.3 [Info][AudioConverter] New Stream: SampleRate=44100, FramesPerPacket=1152, BytesPerFrame=0, ChannelsPerFrame=2
54.8 [Info][AudioConverter] Seeking to msec=53664, frame=2337300, packet=1044, byte=654523
56.9 [Info][AudioConverter] Seeking to msec=101214, frame=4454100, packet=468, byte=293406
58.7 [Info][AudioConverter] Seeking to msec=148765, frame=6526800, packet=720, byte=451395
60.7 [Info][AudioConverter] Seeking to msec=178654, frame=7849800, packet=72, byte=45139
62.1 [Info][AudioConverter] Seeking to msec=93063, frame=4101300, packet=180, byte=112848
63.5 [Info][AudioConverter] Seeking to msec=127027, frame=5600700, packet=828, byte=519105

--- [AudioConverter] packet = (frame / stream_description.FramesPerPacket);
15.0 [Info][AudioConverter] New Stream: SampleRate=44100, FramesPerPacket=1152, BytesPerFrame=0, ChannelsPerFrame=2
19.1 [Info][AudioConverter] Seeking to msec=29209, frame=1288116, packet=1118, byte=700916
26.8 [Info][AudioConverter] Seeking to msec=95780, frame=4223898, packet=3666, byte=2298356
53.4 [Info][AudioConverter] Seeking to msec=140613, frame=6201033, packet=5382, byte=3374182
60.9 [Info][AudioConverter] Seeking to msec=98497, frame=4343717, packet=3770, byte=2363558
65.5 [Info][AudioConverter] Seeking to msec=190881, frame=8417852, packet=7307, byte=4581040
76.3 [Info][AudioConverter] Seeking to msec=74042, frame=3265252, packet=2834, byte=1776744
Comment 1 Sebastien Pouliot 2012-05-15 21:43:42 UTC
Can you tell me if the results are good when the linker is turned off ? (by default it's off on the simulator  and enabled on devices builds). It "sounds" like bug #5034
Comment 2 adam.lickel 2012-05-16 13:45:02 UTC
It behaves the same on the simulator and in the device.
This log is from the simulator.

It shouldn't have anything to do with callbacks.
This function should map to AudioFileStreamGetProperty() with the property kAudioFileStreamProperty_FrameToPacket.
Comment 3 Sebastien Pouliot 2012-05-16 15:07:04 UTC
Ok, thanks for confirming this.

> It shouldn't have anything to do with callbacks.

The similarity with #5034 was not related to callbacks (or even audio) but to the linker removing fields (from class, not value-types) that were needed when p/invoke'ing. That has been fixed (will be in 5.2.12) but could affect existing code (and lead to weird "misplaced" values).
Comment 4 Sebastien Pouliot 2012-05-16 20:02:41 UTC
The code is doing that [1] and a small test case shows the expected progression, e.g.

			for (int i = 0; i < Int32.MaxValue; i += fileStream.StreamBasicDescription.FramesPerPacket) {
				var ret = fileStream.FrameToPacket (i, out offset);
				Console.WriteLine ("{0} {1} {2}", i, ret, offset);

It does smell like a memory corruption but it could be occurring prior to this code (but messing the internal state). I'm looking to see if the bindings/structures are wrong around this... but I'll likely need more specific instructions to duplicate this.

[1] https://github.com/mono/maccore/blob/master/src/AudioToolbox/AudioFileStream.cs#L480
Comment 5 Rolf Bjarne Kvinge [MSFT] 2012-06-01 07:53:46 UTC
The problem is that you're calling FrameToPacket like this:

file_stream.FrameToPacket (frame, out packet);

The out parameter isn't the resulting packet, it's the offset of the frame in the packet. The packet is the return value, so you need to do this:

packet = file_stream.FrameToPacket (frame, out frameOffsetInPacket);