【问题标题】:How to wait finish current audio for playing next audio?如何等待完成当前音频以播放下一个音频?
【发布时间】:2011-07-07 21:58:30
【问题描述】:

我正在使用 cocos2d。如何等待完成当前音频以播放下一个音频?我无法使用 SimpleAudioEngine。

【问题讨论】:

  • 你问的是音效还是背景音乐?

标签: objective-c audio cocos2d-iphone simpleaudioengine


【解决方案1】:

http://www.cocos2d-iphone.org/api-ref/0.99.0/interface_c_d_sound_engine.html

使用 CDAudioEngine。它有你想要的方法。顺便说一句,SimpleAudioEngine 正在使用 CDAudioEngine 播放声音。

编辑

当您的按钮第一次被点击时 - 播放声音并将声音的间隔保存到您的一些 lass 变量中。然后在下一次单击中使用此变量来确定“足够的间隔”。或者只是使用一些最大值。

编辑 2 如果您看一下 SimpleAudioEngine 实现,您会注意到它使用 CDSoundEngine 来播放声音。下面是 SimpleAudioEngine 的 init 方法:

static SimpleAudioEngine *sharedEngine = nil;
static CDSoundEngine* soundEngine = nil;
static CDAudioManager *am = nil;
static CDBufferManager *bufferManager = nil;


-(id) init
{
    if((self=[super init])) {
        am = [CDAudioManager sharedManager];
        soundEngine = am.soundEngine;
        bufferManager = [[CDBufferManager alloc] initWithEngine:soundEngine];
        mute_ = NO;
        enabled_ = YES;
    }
    return self;
}

所以我们也可以访问CDSoundEngine:

CDSoundEngine *engine = [CDAudioManager sharedManager].soundEngine;

在 SimpleAudioEngine 上调用 playEffect 方法时(单击按钮时)保存返回的声音 id。

ALuint soundId = [[SimpleAudioEngine sharedEngine] playEffect:...];

现在我们可以使用 CDSoundEngine 获得间隔:

float seconds = [engine bufferDurationInSeconds:soundId];

这就是答案!

顺便说一句,如果您知道声音 ID,您也可以使用 CDSoundEngine 停止声音。

来自 CocosDenshion.h

@class CDSoundSource;
@interface CDSoundEngine : NSObject <CDAudioInterruptProtocol> {

    bufferInfo      *_buffers;
    sourceInfo      *_sources;
    sourceGroup     *_sourceGroups;
    ALCcontext      *context;
    int             _sourceGroupTotal;
    UInt32          _audioSessionCategory;
    BOOL            _handleAudioSession;
    BOOL            mute_;
    BOOL            enabled_;
    ALfloat         _preMuteGain;

    ALenum          lastErrorCode_;
    BOOL            functioning_;
    float           asynchLoadProgress_;
    BOOL            getGainWorks_;

    //For managing dynamic allocation of sources and buffers
    int sourceTotal_;
    int bufferTotal;

}

@property (readwrite, nonatomic) ALfloat masterGain;
@property (readonly)  ALenum lastErrorCode;//Last OpenAL error code that was generated
@property (readonly)  BOOL functioning;//Is the sound engine functioning
@property (readwrite) float asynchLoadProgress;
@property (readonly)  BOOL getGainWorks;//Does getting the gain for a source work
/** Total number of sources available */
@property (readonly) int sourceTotal;
/** Total number of source groups that have been defined */
@property (readonly) int sourceGroupTotal;

/** Sets the sample rate for the audio mixer. For best performance this should match the sample rate of your audio content */
+(void) setMixerSampleRate:(Float32) sampleRate;

/** Initializes the engine with a group definition and a total number of groups */
-(id)init;

/** Plays a sound in a channel group with a pitch, pan and gain. The sound could played looped or not */
-(ALuint) playSound:(int) soundId sourceGroupId:(int)sourceGroupId pitch:(float) pitch pan:(float) pan gain:(float) gain loop:(BOOL) loop;

/** Creates and returns a sound source object for the specified sound within the specified source group.
 */
-(CDSoundSource *) soundSourceForSound:(int) soundId sourceGroupId:(int) sourceGroupId;

/** Stops playing a sound */
- (void) stopSound:(ALuint) sourceId;
/** Stops playing a source group */
- (void) stopSourceGroup:(int) sourceGroupId;
/** Stops all playing sounds */
-(void) stopAllSounds;
-(void) defineSourceGroups:(NSArray*) sourceGroupDefinitions;
-(void) defineSourceGroups:(int[]) sourceGroupDefinitions total:(int) total;
-(void) setSourceGroupNonInterruptible:(int) sourceGroupId isNonInterruptible:(BOOL) isNonInterruptible;
-(void) setSourceGroupEnabled:(int) sourceGroupId enabled:(BOOL) enabled;
-(BOOL) sourceGroupEnabled:(int) sourceGroupId;
-(BOOL) loadBufferFromData:(int) soundId soundData:(ALvoid*) soundData format:(ALenum) format size:(ALsizei) size freq:(ALsizei) freq;
-(BOOL) loadBuffer:(int) soundId filePath:(NSString*) filePath;
-(void) loadBuffersAsynchronously:(NSArray *) loadRequests;
-(BOOL) unloadBuffer:(int) soundId;
-(ALCcontext *) openALContext;

/** Returns the duration of the buffer in seconds or a negative value if the buffer id is invalid */
-(float) bufferDurationInSeconds:(int) soundId;
/** Returns the size of the buffer in bytes or a negative value if the buffer id is invalid */
-(ALsizei) bufferSizeInBytes:(int) soundId;
/** Returns the sampling frequency of the buffer in hertz or a negative value if the buffer id is invalid */
-(ALsizei) bufferFrequencyInHertz:(int) soundId;

/** Used internally, never call unless you know what you are doing */
-(void) _soundSourcePreRelease:(CDSoundSource *) soundSource;

@end

我正在使用 cocos2D 0.99.5

实现:

-(float) bufferDurationInSeconds:(int) soundId {
    if ([self validateBufferId:soundId]) {
        float factor = 0.0f;
        switch (_buffers[soundId].format) {
            case AL_FORMAT_MONO8:
                factor = 1.0f;
                break;
            case AL_FORMAT_MONO16:
                factor = 0.5f;
                break;
            case AL_FORMAT_STEREO8:
                factor = 0.5f;
                break;
            case AL_FORMAT_STEREO16:
                factor = 0.25f;
                break;
        }   
        return (float)_buffers[soundId].sizeInBytes/(float)_buffers[soundId].frequencyInHertz * factor;
    } else {
        return -1.0f;
    }   
}

【讨论】:

  • 不,我的意思是在播放一些声音时,当我按下按钮时,这个声音不能再次播放。现在我知道当我按下按钮时,声音正在播放,当我再次快速按下按钮时,这个声音播放着未完成的这个声音。
  • 在你的类中创建一个 NSDate 变量。当按下按钮时,使用 +data 方法重新创建变量。然后,当您再次按下按钮时,检查经过了多少毫秒。如果间隔足够 - 播放声音。再次将数据重新创建到当前时刻
  • 我无法设置足够的音程,因为我有超过 100 种音程不同的声音。
  • 你能帮我如何获得声音的间隔吗?
  • @Andrew,CDSoundEngine 没有方法 bufferDurationInSeconds。
【解决方案2】:

// 播放声音 Aluint soundID = [[SimpleAudioEngine sharedEngine] playEffect:@"sound.mp3"];

// 停止声音播放时需要使用相同的 soundID [[SimpleAudioEngine sharedEngine] stopEffect:soundID];

【讨论】:

  • 我知道这个方法。以我的方式我无法使用它。
猜你喜欢
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多