开发者

How to start Audio file from certain location using AudioQueue?

开发者 https://www.devze.com 2023-01-08 14:04 出处:网络
I have analyzed \"SpeakHere\" sample code of iPhone dev forum. There is a code for starting AudioQueue as following..

I have analyzed "SpeakHere" sample code of iPhone dev forum.

There is a code for starting AudioQueue as following..

AudioTimeStamp ats = {0};
AudioQueueStart(mQueue, &a开发者_高级运维ts);

But I have no idea that how to start middle of file.

I changed AudioTimeStamp with various values include negative. But it does not works.

Please let me know your great opinion. Thanks.


AudioQueueStart is not the function that will help you to do that. The time there is like a delay, if you pass NULL then it means that the queue will start ASAP.

You have to pass the frame you want to play and enqueue it, to calculate that you have to know the number of frames your file has and the (relative) position you want to play.

These are instructions how to make it in SpeakHere

In the new (objc++ based) SpeakHere

In AQPlayer.h add a private instance variable:

UInt64 mPacketCount;

and a public method:

void SetQueuePosition(float position) { mCurrentPacket = mPacketCount*position; };

In AQPlayer.mm inside AQPlayer::SetupNewQueue() before mIsInitialized = true; add:

// get the total number of packets
UInt32 sizeOfPacketsCount = sizeof(mPacketCount);
XThrowIfError (AudioFileGetProperty (mAudioFile, kAudioFilePropertyAudioDataPacketCount, &sizeOfPacketsCount, &mPacketCount), "get packet count");

Now you have to use it (In SpeakHereControler.mm add this and link it to a UISlider for example):

- (IBAction) sliderValueChanged:(UISlider *) sender
{
    float value = [sender value];
    player->SetQueuePosition(position);
}

Why this works:

The playback callback function AudioQueueOutputCallback that feeds the queue with new packets and which in the new SpeakHere is: void AQPlayer::AQBufferCallback( , , ) calls AudioFileReadPackets to read and enqueue a certain part of a file. For that task mCurrentPacket is used and that is what we just adjusted in above methods, hence the part you wanted to play is read, enqueued and finally played :)


Just for historical reasons :)

In the old (objc based) SpeakHere

In AudioPlayer.h add an instance variable:

UInt64      totalFrames;

AudioPlayer.m inside - (void) openPlaybackFile: (CFURLRef) soundFile add:

UInt32 sizeOfTotalFrames = sizeof(UInt64);
AudioFileGetProperty (                        
          [self audioFileID], 
          kAudioFilePropertyAudioDataPacketCount,
          &sizeOfTotalFrames,
          &totalFrames
          );

Then add a method to AudioPlayer.h and .m

- (void) setRelativePlaybackPosition: (float) position 
{
    startingPacketNumber = totalFrames * position;
}

Now you have to use it (In AudioViewController add this and link it to a UISlider for example):

- (IBAction) setPlaybackPosition: (UISlider *) sender
{
    float value = [sender value];
    [audioPlayer setRelativePlaybackPosition: value];
}

When value is 0 you will play from the beggining, 0.5 from the middle, etc.


Hope this helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消