MusicSequenceFileLoad在iOS10上返回-1(AudioToolbox / MusicPlayer)

时间:2016-09-11 14:36:14

标签: objective-c midi ios10 audiotoolbox

更新2016年10月9日:我已经在2016年9月22日与Apple打开了雷达#28425770,因为以下缺陷而且他们刚刚标记为重复(雷达#28327056) ),所以这似乎是iOS10中的已知错误。

我在调用AudioToolbox / MusicPlayer API方法“MusicSequenceFileLoad()”时遇到错误,将MIDI文件的内容(从给定的URL)加载到iOS10 iPad Pro(wifi模型)上的音乐序列中非常感谢社区对此进行调试的一些帮助。

迄今为止我能够做出的研究/观察:

  • 此代码在iOS7,8和9上的生产中已经有2年以上没有问题,并且在iOS 10 Simulator上运行没有问题,但仅在iOS 10.0.1 iPad Pro Wifi上返回错误模型。

  • 我无法在其他设备上重新创建,也请一些朋友尝试。经过测试的设备没有问题:iPhone 6 +,iPad Mini第4代,iPad Pro Cellular。

  • 第一次显示使用此MIDI文件的VC时,所有处理都没有任何问题。这是应用程序崩溃时加载VC的第二次(或有时是第三次)。可以在100%的时间内始终如一地重新创建该问题。

  • 通过调用此函数检查OSStatus结果代码只返回值-1,并不表示失败的原因。

  • 在Xcode中调试时,没有崩溃报告,异常信息或调用堆栈。

  • 内存管理问题(分配,泄漏,僵尸)的分析未显示与崩溃相关的任何信息;打开Zombie Objects选项并没有显示任何Zombie Objects。

  • 分析应用程序并未显示任何未释放内存的区域。

  • 将对象更改为静态没有任何影响所以这似乎与内存无关。

如果有人对我可以调试此问题的其他方式有任何建议,我们将不胜感激。我原本以为它可能与内存管理有关但是我可以看到我正在适当地处理内存(使用ARC作为应用程序并根据需要发布C-API对象)并且分析没有发现任何我能看到的问题。

代码示例:

@property (readwrite, nonatomic) MusicPlayer midiMusicPlayer;
@property (readwrite, atomic) MusicSequence masterMidiMusicSequence;

- (void)initializeMusicPlayerAndMasterSequenceWithFile:(NSString *)midiFilename
{
    CheckError(NewMusicPlayer(&_midiMusicPlayer), "NewMusicPlayer: _midiMusicPlayer");
    CheckError(NewMusicSequence(&_masterMidiMusicSequence), "NewMusicSequence: _masterMidiMusicSequence");

    NSString *midiFilePath = [NSBundle pathForResource:midiFilename
                                                ofType:@"mid"
                               checkDocumentsDirectory:YES];
    NSURL *midiFileURL = [NSURL fileURLWithPath:midiFilePath];

    // Crash is encountered on the following line:
    CheckError(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
}

2 个答案:

答案 0 :(得分:1)

我通过Core Audio Mailing List收到了Apple工程师的一些指导,并已在iOS10中成功实施了针对此问题的解决方案。

通过更新" errno"呼叫失败后,将值设为0,随后调用' MusicSequenceFileLoad'产生成功的回应。因此,我修改了我的代码如下:

OSStatus statusOfInitialAttempt = CheckError(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
if (statusOfInitialAttempt == -1) {
    errno = 0;

    OSStatus statusOfSecondAttempt = CheckErrorAndReturnOnFailure(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");

    if (statusOfSecondAttempt == -1) {
        // Handle error case
    }
}

... CheckError()函数只是根据已知的OSStatus代码检查OSStatus返回值,类似于this one on GitHub(最初由Chris Adamson from his blog post / presentation "Core Audio Cranks It Up"创建)。

据我所知,根据Core Audio Mailing List上发布的内容,预计此问题将在未来的iOS更新中得到解决。

答案 1 :(得分:0)

您是否尝试将Info.plist添加到 public void jniTemporizedCallback(int buf[]) { // Initialize bitmapOriginal = Bitmap.createBitmap(///) /* set data to original sized bitmap */ bitmapOriginal.setPixels(buf, 0, origWidth, 0, 0, origWidth, origHeight); /* calculate the stretched one */ bitmapStretched = Bitmap.createScaledBitmap(bitmapOriginal, width, height,false); /* tell the main thread to update the image view */ runOnUiThread(runnable); }

  

从iOS 10开始,您的Info.plist文件必须包含一个用途字符串,以便在每个此类项目的权限警报中显示。如果您的应用尝试访问受保护的项目而未提供相应的用途字符串,则您的应用已退出。

有关详细信息,请参阅App Programming Guide for iOS