iphone - 如何在 iPhone 上使用 OpenAL 播放循环声音

标签 iphone objective-c audio openal loops

我正在学习有关使用 OpenAL 播放声音的教程。现在一切正常,除了我不能让声音循环播放。我相信我已经使用 AL_LOOPING 作为源代码。现在它只能播放一次,当播放结束时,应用程序将被阻止(不响应我点击播放按钮)。关于代码有什么问题的任何想法?

// start up openAL
// init device and context
-(void)initOpenAL
{
    // Initialization
    mDevice = alcOpenDevice(NULL); // select the "preferred device"
    if (mDevice) {
        // use the device to make a context
        mContext = alcCreateContext(mDevice, NULL);
        // set my context to the currently active one
        alcMakeContextCurrent(mContext);
    }
}


// open the audio file
// returns a big audio ID struct
-(AudioFileID)openAudioFile:(NSString*)filePath
{
    AudioFileID outAFID;
    // use the NSURl instead of a cfurlref cuz it is easier
    NSURL * afUrl = [NSURL fileURLWithPath:filePath];

    // do some platform specific stuff..
#if TARGET_OS_IPHONE
    OSStatus result = AudioFileOpenURL((CFURLRef)afUrl, kAudioFileReadPermission, 0, &outAFID);
#else
    OSStatus result = AudioFileOpenURL((CFURLRef)afUrl, fsRdPerm, 0, &outAFID);
#endif
    if (result != 0) NSLog(@"cannot openf file: %@",filePath);
    return outAFID;
}


// find the audio portion of the file
// return the size in bytes
-(UInt32)audioFileSize:(AudioFileID)fileDescriptor
{
    UInt64 outDataSize = 0;
    UInt32 thePropSize = sizeof(UInt64);
    OSStatus result = AudioFileGetProperty(fileDescriptor, kAudioFilePropertyAudioDataByteCount, &thePropSize, &outDataSize);
    if(result != 0) NSLog(@"cannot find file size");
    return (UInt32)outDataSize;
}

- (void)stopSound
{
    alSourceStop(sourceID);
}

-(void)cleanUpOpenAL:(id)sender
{
    // delete the sources
    alDeleteSources(1, &sourceID);

    // delete the buffers
    alDeleteBuffers(1, &bufferID);

    // destroy the context
    alcDestroyContext(mContext);

    // close the device
    alcCloseDevice(mDevice);
}

-(IBAction)play:(id)sender
{
    alSourcePlay(sourceID);
}


#pragma mark -
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    [self initOpenAL];
    // get the full path of the file
    NSString* fileName = [[NSBundle mainBundle] pathForResource:@"sound" ofType:@"caf"];
    // first, open the file
    AudioFileID fileID = [self openAudioFile:fileName];

    // find out how big the actual audio data is
    UInt32 fileSize = [self audioFileSize:fileID];

    // this is where the audio data will live for the moment
    unsigned char * outData = malloc(fileSize);

    // this where we actually get the bytes from the file and put them
    // into the data buffer
    OSStatus result = noErr;
    result = AudioFileReadBytes(fileID, false, 0, &fileSize, outData);
    AudioFileClose(fileID); //close the file

    if (result != 0) NSLog(@"cannot load effect: %@", fileName);

    //NSUInteger bufferID;              // buffer is defined in head file
    // grab a buffer ID from openAL
    alGenBuffers(1, &bufferID);

    // jam the audio data into the new buffer
    alBufferData(bufferID, AL_FORMAT_STEREO16, outData, fileSize, 8000); 


    //NSUInteger sourceID;              // source is defined in head file

    // grab a source ID from openAL
    alGenSources(1, &sourceID); 

    // attach the buffer to the source
    alSourcei(sourceID, AL_BUFFER, bufferID);
    // set some basic source prefs
    alSourcef(sourceID, AL_PITCH, 1.0f);
    alSourcef(sourceID, AL_GAIN, 1.0f);
    alSourcei(sourceID, AL_LOOPING, AL_TRUE);

    // clean up the buffer
    if (outData)
    {
        free(outData);
        outData = NULL;
    }
}

最佳答案

您应该能够在调用 alBufferData() 后立即释放 outData。它排除了它作为罪魁祸首,你可以尝试静态扩展并自己管理内存。它是这样的:

alBufferDataStaticProcPtr alBufferDataStaticProc = (alBufferDataStaticProcPtr)alcGetProcAddress(0, (const ALCchar *)"alBufferDataStatic");
alBufferDataStaticProc(bufferID, bitChanFormat, audioData, audioDataSize, dataFormat.mSampleRate);

关于iphone - 如何在 iPhone 上使用 OpenAL 播放循环声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1873817/

相关文章:

javascript - HTML 5 地理定位在 Safari 中不起作用

iphone - Webview 不会返回到原始页面

windows - 每次按下按钮时播放音频 - flutter

iphone - 直接从应用程序转到地址簿/联系电话

iphone - UITableView titleForSection 字体

ios - 旋转 UISplitViewController 后模态消失

ios - iPhone 从键中的值获取数组的索引

iphone - 避免自动释放对象,好的做法还是矫枉过正?

ios - 使用 Accelerate 和 vDSP_desamp() 进行音频处理

api - 有没有办法通过SoundCloud javascript流API强制使用MP3 block ?