Bug 16949 - Concatenating audio files fails on first playback
Summary: Concatenating audio files fails on first playback
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 7.0.2.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Rolf Bjarne Kvinge [MSFT]
Depends on:
Reported: 2013-12-23 20:18 UTC by Jon Goldberger [MSFT]
Modified: 2015-11-12 07:58 UTC (History)
2 users (show)

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

Test Project (22.13 KB, application/zip)
2013-12-23 20:18 UTC, Jon Goldberger [MSFT]

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:

Comment 1 Jon Goldberger [MSFT] 2013-12-23 20:19:23 UTC
Recently while working on an audio-based application targeting IOS7 through Xamarin Studio, I encountered a bizarre issue that I am unsure if it is possibly a bug within the IOS environment or a silly error that I may have made myself. I have created a sample application which I am including a Dropbox link to within this e-mail (due to size constraints).

Basically, this proof-of-concept involves the use of "overwriting" an existing audio recording by allowing the user to move a slider element to a specific position to begin recording and when recording is stopped, it will trim the original file and concatenate the current "temporary" recording essentially overwriting any previous content. It uses two separate NSUrl references that each refer to both the main file and a temporary one, the main file being the overall recording and the temporary one being any subsequent recordings that may overwrite the additional content of the file.

The following steps provide a basic breakdown of what is occurring in the application :

1. A User clicks "Record" and begins recording some audio. (This will create a file that points to our "main audio" URL)

2. When finished, the user will click the "Pause" button. (This works just fine, you can play the audio here without any issue)

3. The user could then slide the available slider to a specific position to designate where an "overwrite" should occur.

4. If the user clicks "Record" again at this position, it will note the position that recording began on (for later trimming purposes) and it will begin recording pointing to the "temporary audio" URL reference. (This is so that we will have our previous recording and our current temporary recording)

5. When recording is stopped (and a temporary file is present), the application will "render" the file. Rendering the file consists of the following operations :

a. Create three separate file references (a trimmed file, a new file and a working file).

b. It will copy the "main audio" content to the working file (this is our audio content prior to the current temporary recording)

c. It will perform a trim operation (trimming the working file from the beginning to the trimming position mentioned above) and store the result of that operation in the "trimmed file".

d. It will perform another operation and concatenate the trimmed file content with the current temporary recording (essentially overwriting anything beyond the trim position and replacing it with the temporary recording) into a new file.

e. Finally, it will copy the contents of this new file to our original "main audio" URL so that it will play the entire recording when play is pressed.

The issue that I have encountered is occurring after the Render step above. When you attempt to play the file after performing an overwrite operation, it will only play the contents of the "trimmed file" and the remainder of the recording will be "empty space" (where the temporary recording was). The bizarre thing is that when the pause button is pressed after doing this and you attempt to play the file again, it will play the entire overwritten recording as intended (which I would expect that it would have done on the initial playback after recording for the second time).

You can reproduce this same exact issue by doing the following :

1. Record a 10 second recording.

2. After recording, slide the slider to 5 seconds into the Recording.

3. Continue recording for several more seconds.

4. Press pause to stop the recording.

5. Slide the slider to the beginning (0 position) and press Play. (It should play your initial recording for 5 seconds and then have x seconds of "dead audio")

6. Press pause and slide it back to the beginning of the slider and press Play again. (It will now play the entire recording as intended)

Again, I am not sure if this is a bug or strange issue regarding the use of File References being incorrect or the garbage disposal within the player object itself (as it seems to be hanging on to the "trimmed file") or if it is simply an egregious error on our part. But I thought that you would be the best source to ask and I wanted you to be aware of it in case it indeed was a bug of some kind.
Comment 3 Jon Goldberger [MSFT] 2014-07-15 18:46:45 UTC
From case:

The Proof-of-Concept application that I attached to the bug report still holds true and occurs within iOS 7 (specifically 7.1.2), however it seems to be device-specific. For instance, I have two iPhones that I have been testing with, one being an iPhone 5 and the other being an iPhone 4. When testing with the iPhone 5, the recording seems to work as intended and the overwrite functionality works just fine (eg make a 10 second recording, move slider to 5 seconds and start recording and it will successfully concatenate the files) however on an iPhone 4, it will only play the first part of the recording (prior to where the “trim” occurred).
Comment 4 Jon Goldberger [MSFT] 2014-07-15 19:08:21 UTC
I have verified the above, that the test project works as expected on an iPhone 5s, but not on an iPhone 4, both running the same iOS version, 7.1.2.

Repro Steps:

1. Open test project and launch on an iPhone 5 or 5s (client tested on an iPhone 5 and says it works as expected there as well)
2. Press the Record button and Record ten seconds of audio, a count to ten works well.
3. Press the Pause button.
4. Slide the slider back to 5 seconds.
5. Press the record button and record another 10 seconds of audio (count to ten)
6. Press the Pause button.
7. Slide the slider back to 0:00
8. Press the Play button

Expected result: Will hear first count to ten interrupted by the second count.
Actual result (on iPhone 5/5s): As expected.

Repeat above launching to an iPhone 4 instead. 

Expected result: Will hear first count to ten interrupted by the second count.
Actual result (on iPhone 4): First count is heard up to the point where the second count should start, 5 seconds in, but then there is only silence after that point.
Comment 5 Rolf Bjarne Kvinge [MSFT] 2014-07-16 08:14:25 UTC
I haven't been able to reproduce this, since I don't have an iPhone 4 with iOS 7 (I have one with iOS 5.1.1, but the sample doesn't work with that iOS version).

Jon, could you transfer the file from the iOS device [1] and try to play it on the Mac? That way we'll at least be able to determine if it's the playback which is failing or the audio file processing.

[1] I've used iExplorer before to get files from the device (http://www.macroplant.com/iexplorer/), but there are other options out there.
Comment 6 Jon Goldberger [MSFT] 2014-07-16 12:00:31 UTC

OK, I got the files from the device. You can use Xcode to download the app and then "Show Package Contents" to get the files.

To be clear, here is what I did:

1. Launched app
2. Made a 10 second recording counting to ten
3. Pressed pause
4. Moved the slider back to 5 seconds
5. Pressed record
6. recorded another 10 seconds of audio.
7. Pressed pause.
8. Opened Xcode and downloaded the app.
9. Got the Audio files from the downloaded app package.

Results: Audio.aac had the complete concatenated recording, with the first count interrupted by the second count. Temp.aac just and the second recording as expected. 

I did the same on the iPhone 5s and the results were identical.
Comment 7 Rolf Bjarne Kvinge [MSFT] 2014-07-17 11:34:40 UTC
Then it really doesn't sound like something in Xamarin.iOS or that we can fix.

What happens if you create a file with a different name after concatenating the audio?

So say you record to file A.aac, then move back and record to B.aac. Finally when concatenating you create C.aac, and that's the file you play.

That should work around any iOS caching issues, since you'll be playing a new file, not a modified one.
Comment 8 Rolf Bjarne Kvinge [MSFT] 2015-04-16 10:25:09 UTC
@Jon, were you able to try what I suggested in comment #7?
Comment 9 Rolf Bjarne Kvinge [MSFT] 2015-11-12 07:58:22 UTC
No answer; closing.