gpt4 book ai didi

objective-c - 音频文件播放无音量

转载 作者:行者123 更新时间:2023-12-03 01:55:25 26 4
gpt4 key购买 nike

我使用Apple Audio Queue Services指南制作了一个命令行类型的应用程序,以从磁盘播放文件

#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
#define kNumberBuffers 3 // the number of audio queue buffers to use

//An AudioStreamBasicDescription structure (from CoreAudioTypes.h) representing the audio data format of the file being played. This format gets used by the audio queue specified in the mQueue field.

typedef struct AQPlayerState{
AudioStreamBasicDescription mDataFormat;
AudioQueueRef mQueue; //The playback audio queue created by your application.
AudioQueueBufferRef mBuffers[kNumberBuffers]; //An array holding pointers to the audio queue buffers managed by the audio queue.
AudioFileID mAudioFile; //An audio file object that represents the audio file your program plays.
UInt32 bufferByteSize; //The size, in bytes, for each audio queue buffer.
SInt64 mCurrentPacket;//The packet index for the next packet to play from the audio file.
UInt32 mNumPacketsToRead; //The number of packets to read on each invocation of the audio queue’s playback callback
AudioStreamPacketDescription *mPacketDecs; //For VBR audio data, the array of packet descriptions for the file being played. For CBR data, the value is NULL.
BOOL isRunning;
}AQPlayerState;

static void HandleOutputBuffer(
void *AQData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer
){
OSStatus error;
AQPlayerState *pAQData=(AQPlayerState*)AQData;
if(!pAQData->isRunning)return;
UInt32 numBytesReadFromFile; // A variable to hold the number of bytes of audio data read from the file being played.

UInt32 numPackets=pAQData->mNumPacketsToRead; // Initializes the numPackets variable with the number of packets to read from the file being played.
error=AudioFileReadPacketData(pAQData->mAudioFile,
false,
&numBytesReadFromFile,
pAQData->mPacketDecs,
pAQData->mCurrentPacket,
&numPackets,
inBuffer->mAudioData
);
assert(error==noErr);
// Tests whether some audio data was retrieved from the file. If so, enqueues the newly-filled buffer. If not, stops the audio queue.
if(numPackets > 0){
inBuffer->mAudioDataByteSize=numBytesReadFromFile; //Tells the audio queue buffer structure the number of bytes of data that were read.

error=AudioQueueEnqueueBuffer(pAQData->mQueue,inBuffer,
(pAQData->mPacketDecs ? numPackets : 0),
pAQData->mPacketDecs);
pAQData->mCurrentPacket+=numPackets; //Increments the packet index according to the number of packets that were read.
}else{
AudioQueueStop(pAQData->mQueue,0);
pAQData->isRunning=0;
}


}
void DeriveBufferSize(
AudioStreamBasicDescription *ASBDesc,
UInt32 maxPacketSize,
Float64 seconds,
UInt32 *outBufSize,
UInt32 *outNumPacketsToRead
){
static const int maxBufSize=0x50000;
static const int minBufSize=0x4000;

if(ASBDesc->mFramesPerPacket!=0){
Float64 numPacketsForTime=
ASBDesc->mSampleRate/ASBDesc->mFramesPerPacket * seconds;
*outBufSize=numPacketsForTime *maxPacketSize;
}else{
*outBufSize=maxBufSize > maxPacketSize ? maxBufSize : maxPacketSize;
}
if ( // 10
*outBufSize > maxBufSize &&
*outBufSize > maxPacketSize
)
*outBufSize = maxBufSize;
else { // 11
if (*outBufSize < minBufSize)
*outBufSize = minBufSize;
}
*outNumPacketsToRead = *outBufSize / maxPacketSize; // 12

}
int main(int argc, const char * argv[]) {
AQPlayerState AQPlayer;
CFURLRef audioFileURL=CFURLCreateFromFileSystemRepresentation(NULL,
(const UInt8*)argv[1], strlen(argv[1]),0);
OSStatus result;
result=AudioFileOpenURL(audioFileURL,fsRdPerm, 0,&AQPlayer.mAudioFile);
UInt32 dataFormatSize=sizeof(AQPlayer.mDataFormat);
AudioFileGetProperty(AQPlayer.mAudioFile,kAudioFilePropertyDataFormat,&dataFormatSize,&AQPlayer.mDataFormat);
// Create playback queue
AudioQueueNewOutput(&AQPlayer.mDataFormat,
HandleOutputBuffer,
&AQPlayer,
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&AQPlayer.mQueue);
// Setting Buffer Size and Number of Packets to Read
UInt32 maxPacketSize;
UInt32 propertySize=sizeof(maxPacketSize);
// Getting audio File maximum packet size
AudioFileGetProperty(AQPlayer.mAudioFile,kAudioFilePropertyPacketSizeUpperBound,&propertySize,&maxPacketSize);
DeriveBufferSize(&AQPlayer.mDataFormat,maxPacketSize,0.5,&AQPlayer.bufferByteSize,&AQPlayer.mNumPacketsToRead);
// Allocating memory for a packet descriptions array
bool isFormatVBR=(AQPlayer.mDataFormat.mBytesPerPacket == 0 ||
AQPlayer.mDataFormat.mFramesPerPacket == 0);
if(isFormatVBR){
AQPlayer.mPacketDecs=(AudioStreamPacketDescription*)malloc(AQPlayer.mNumPacketsToRead*sizeof(AudioStreamPacketDescription));
}
else{
AQPlayer.mPacketDecs=NULL;
}
// Setting a magic cookie for a playback audio queue
UInt32 cookieSize=sizeof(UInt32);
// Captures the result of the AudioFileGetPropertyInfo function. If successful, this function returns a value of NoErr, equivalent to Boolean false.
bool couldNotGetProperty=AudioFileGetProperty(AQPlayer.mAudioFile,kAudioFilePropertyMagicCookieData,&cookieSize,NULL);
if(!couldNotGetProperty && cookieSize){
char* magicCookie=malloc(cookieSize);

AudioFileGetProperty(AQPlayer.mAudioFile,kAudioFilePropertyMagicCookieData,&cookieSize,magicCookie);

AudioQueueSetProperty(AQPlayer.mQueue,kAudioQueueProperty_MagicCookie,magicCookie,cookieSize);

free(magicCookie);
}
AQPlayer.mCurrentPacket=0;
for(int i =0;i<kNumberBuffers;++i){
AudioQueueAllocateBuffer(AQPlayer.mQueue,AQPlayer.bufferByteSize,&AQPlayer.mBuffers[i]);
HandleOutputBuffer(&AQPlayer,AQPlayer.mQueue,AQPlayer.mBuffers[i]);
}
Float32 gain=1.0; // Set Full Volume for playback
AudioQueueSetParameter(AQPlayer.mQueue,kAudioQueueParam_Volume,gain);
// start and play
AQPlayer.isRunning=true;
AudioQueueStart(AQPlayer.mQueue,NULL);
do{
CFRunLoopRunInMode(kCFRunLoopDefaultMode,0.25,false);
}while(AQPlayer.isRunning);
CFRunLoopRunInMode(kCFRunLoopDefaultMode,1,false);

// Cleaning up after playing an audio file
AudioQueueDispose(AQPlayer.mQueue,true);
AudioFileClose(AQPlayer.mAudioFile);
free(AQPlayer.mPacketDecs);
return 0;
}

一切都可以正确构建和编译,但是当应用运行时,即使将 kAudioQueueParam_Volume设置为1.0,我也听不到扬声器或耳机的声音

最佳答案

这可能是由于在完全调用音频回调之前,退出了一个命令行应用程序,并且该调用被调用了足够的时间以覆盖文件的整个长度。您需要一些代码(运行循环和/或NSTimer?)来防止应用退出。

关于objective-c - 音频文件播放无音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35949964/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com