err = AudioQueueDispose(queue, true);
Run Code Online (Sandbox Code Playgroud)
我使用true这样处理AudioQueue立即发生,虽然它有时会立即处理队列,有时它在设备上延迟3-4秒到13秒.err = AudioQueueStop(queue, true)也有同样的问题.
我的理解是两个函数都尝试刷新释放缓冲区并且即将被排队......
所以我甚至会帮助我的回调函数来刷新缓冲区,如果AudioQueueDispose要调用的话.
static void MyAQOutputCallBack(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer)
{
if (player.shouldDispose) {
printf("player shouldDispose !!!!!!!!!!!\n\n\n\n\n\n");
OSStatus dispose = AudioQueueFlush (inAQ);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
由于我要AudioQueues在播放曲目后使用录制内容,因此我需要在没有延迟的情况下返回此函数.几百毫秒还可以,但3-4秒?这是不可接受的.
其他AudioQueue函数也在同一个线程上调用,它们似乎工作正常.
我也尝试在主线程上调用它来确保它是否会改变任何东西
[self performSelectorOnMainThread:@selector(tryOnMain) withObject:nil waitUntilDone:NO];
要么
dispatch_sync(dispatch_get_main_queue(),^{ 没有任何区别
知道可能会发生什么吗?
我正在寻找使用音频队列服务的示例.
我想用数学方程创造一个声音,然后听到它.
我正在为iPhone编写远程桌面客户端,我正在尝试实现音频重定向.
客户端通过套接字连接连接到服务器,服务器一次发送32K块PCM数据.
我正在尝试使用AQS播放数据,它播放前两秒(1个缓冲区值).但是,由于下一个数据块尚未进入套接字,因此下一个AudioQueueBuffer为空.当数据进入时,我用数据填充下一个可用缓冲区并将其与AudioQueueEnqueueBuffer一起排队.但是,它永远不会播放这些缓冲区.
如果队列中没有缓冲区,队列是否会停止播放,即使您稍后添加了缓冲区?
这是代码的相关部分:
void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
if(items_in_queue == NUM_BUFFERS){
return;
}
if(!playState.busy){
OSStatus status;
status = AudioQueueNewOutput(&playState.dataFormat, AudioOutputCallback, &playState, CFRunLoopGetCurrent(), NULL, 0, &playState.queue);
if(status == 0){
for(int i=0; i<NUM_BUFFERS; i++){
AudioQueueAllocateBuffer(playState.queue, 40000, &playState.buffers[i]);
}
AudioQueueAddPropertyListener(playState.queue, kAudioQueueProperty_IsRunning, MyAudioQueuePropertyListenerProc, &playState);
status = AudioQueueStart(playState.queue, NULL);
if(status ==0){
playState.busy = True;
}
else{
return;
}
}
else{
return;
}
}
playState.buffers[queue_hi]->mAudioDataByteSize = s->size;
memcpy(playState.buffers[queue_hi]->mAudioData, s->data, s->size);
AudioQueueEnqueueBuffer(playState.queue, playState.buffers[queue_hi], 0, 0);
queue_hi++;
queue_hi = queue_hi % NUM_BUFFERS;
items_in_queue++; …Run Code Online (Sandbox Code Playgroud) 我制作了一个流媒体音乐播放器,它在前台运行良好.但在后台iOS4中,它不会自动播放下一首歌曲.(遥控器工作)原因是AudioQueueStart return -12985.
我已经检查了音频会话.它很好.我AudioQueueStart开始播放音乐时使用.你怎么能删除AudioQueueStart?
- (void)play
{
[self setupAudioQueueBuffers]; // calcluate the size to use for each audio queue buffer, and calculate the // number of packets to read into each buffer
OSStatus status = AudioQueueStart(self.queueObject, NULL);
}
Run Code Online (Sandbox Code Playgroud)
我在网上读到了关于AudioQueueStart失败主题的答案.
要检查的一件事是AudioSession首先处于活动状态.在我的情况下,我之前在开始播放新歌之前将会话设置为在歌曲更改之间处于非活动状态:
AudioSessionSetActive(false);
一旦我删除了这个AudioQueueStart从后台工作得很好.
当我的应用程序处于iOS4.0的后台时,我在启动AudioQueue时遇到困难.当应用程序处于活动状态时,代码工作正常,但在后台运行时代码失败,但代码失败.
err = AudioQueueStart( queueObject, NULL );
if( err )
{
NSLog(@"AudioQueueStart failed with %d", err);
= NO;
AudioQueueStop(queueObject, YES);
return;
}
Run Code Online (Sandbox Code Playgroud)
对于上面的代码,err设置为-12985
我想从应用程序包中读取声音文件,复制它,播放其最大音量级别(增益值或峰值功率,我不确定它的技术名称),然后将其作为另一个文件写入捆绑包再次.
我做了复制和写作部分.生成的文件与输入文件相同.我在AudioToolbox框架中使用AudioFile服务的AudioFileReadBytes()和AudioFileWriteBytes()函数来做到这一点.
所以,我有输入文件的字节以及它的音频数据格式(通过使用带有kAudioFilePropertyDataFormat的AudioFileGetProperty())但是我找不到这些中的变量来播放原始文件的最大音量级别.
为了澄清我的目的,我正在尝试生成另一个声音级别相对于原始级别增加或减少的声音文件,所以我不关心系统的音量级别,这是由用户或iOS设置的.
这可能与我提到的框架有关吗?如果没有,还有其他建议吗?
谢谢
编辑:通过Sam关于某些音频基础知识的答案,我决定用另一种方法扩展问题.
我可以使用AudioQueue服务将现有声音文件(在捆绑中)录制到另一个文件,并在录制阶段播放音量级别(借助框架)吗?
更新:这是我如何读取输入文件和写入输出.下面的代码降低了"一些"幅度值的声级,但噪声很大.有趣的是,如果我选择0.5作为幅度值,它会增加声级而不是降低它,但是当我使用0.1作为幅度值时,它会降低声音.两种情况都涉及令人不安的噪音.我认为这就是为什么Art正在谈论规范化,但我不知道规范化.
AudioFileID inFileID;
CFURLRef inURL = [self inSoundURL];
AudioFileOpenURL(inURL, kAudioFileReadPermission, kAudioFileWAVEType, &inFileID)
UInt32 fileSize = [self audioFileSize:inFileID];
Float32 *inData = malloc(fileSize * sizeof(Float32)); //I used Float32 type with jv42's suggestion
AudioFileReadBytes(inFileID, false, 0, &fileSize, inData);
Float32 *outData = malloc(fileSize * sizeof(Float32));
//Art's suggestion, if I've correctly understood him
float ampScale = 0.5f; //this will reduce the 'volume' by -6db
for (int i = 0; i < fileSize; i++) {
outData[i] = (Float32)(inData[i] …Run Code Online (Sandbox Code Playgroud) 我正在使用AudioQueue编写iOS应用程序进行录制.我创建一个配置为获得线性PCM的输入队列,声明此队列,一切都按预期工作.
为了管理中断,我实现了AVAudioSession的委托方法来捕获中断的开始和结束.endInterruption方法如下所示:
- (void)endInterruptionWithFlags:(NSUInteger)flags;
{
if (flags == AVAudioSessionInterruptionFlags_ShouldResume && audioQueue != 0) {
NSLog(@"Current audio session - category: '%@' mode: '%@'",
[[AVAudioSession sharedInstance] category],
[[AVAudioSession sharedInstance] mode]);
NSError *error = nil;
OSStatus errorStatus;
if ((errorStatus = AudioSessionSetActive(true)) != noErr) {
error = [self errorForAudioSessionServiceWithOSStatus:errorStatus];
NSLog(@"Could not reactivate the audio session: %@",
[error localizedDescription]);
} else {
if ((errorStatus = AudioQueueStart(audioQueue, NULL)) != noErr) {
error = [self errorForAudioQueueServiceWithOSStatus:errorStatus];
NSLog(@"Could not restart the audio queue: %@",
[error localizedDescription]);
}
} …Run Code Online (Sandbox Code Playgroud) 我试图kAudioSessionCategory_RecordAudio在我的应用程序在后台唤醒但不是最前沿(例如在重要的位置更改期间,我已经看到商店中的其他应用程序执行此操作,因此我知道它是可能的).但是每当我尝试像这样开始音频会话时
CheckError(AudioQueueStart(queue,
NULL),
"AudioQueueStart failed");
我收到此错误:
Error: AudioQueueStart failed (-12985)
所以我读到了这一点,但只有建议是将音频会话设置为活动,AudioSessionSetActive(YES)但也会因'!cat'错误而失败.显然你可以尝试切换音频会话的活动状态,但这对我没用.
我有音频背景模式plist标志设置并开始音频会话,而我的应用程序是最前面,然后切换到另一个应用程序工作(显示红色条显示它正在录制).它只是启动音频会话而应用程序不是最前沿的问题.
有没有人有一个示例项目我可以看看演示在后台开始录制音频会话?
注意:我正在寻找使用音频队列的解决方案,因为我需要缓冲区中的音频,而不是文件.
我正在使用音频队列来播放音频文件.我需要精确计时最后一个缓冲区.我需要在播放最后一个缓冲区后的150ms-200ms内通知一个函数...
通过回调方法我知道有多少缓冲区被排队
我知道缓冲区大小,我知道上一个缓冲区填充了多少字节.
首先,我初始化一些缓冲区,然后用音频数据填充缓冲区,然后将它们排队.当音频队列需要填充缓冲区时,它会调用回调并用缓冲区填充数据.
当没有更多可用的音频数据时,Audio Queue会向我发送最后一个空缓冲区,所以我用我拥有的任何数据填充它:
if (sharedCache.numberOfToTalPackets>0)
{
if (currentlyReadingBufferIndex==[sharedCache.baseAudioCache count]-1) {
inBuffer->mAudioDataByteSize = (UInt32)bytesFilled;
lastEnqueudBufferSize=bytesFilled;
err=AudioQueueEnqueueBuffer(inAQ,inBuffer,(UInt32)packetsFilled,packetDescs);
if (err) {
[self failWithErrorCode:err customError:AP_AUDIO_QUEUE_ENQUEUE_FAILED];
}
printf("if that was the last free packet description, then enqueue the buffer\n");
//go to the next item on keepbuffer array
isBufferFilled=YES;
[self incrementBufferUsedCount];
return;
}
}
Run Code Online (Sandbox Code Playgroud)
当音频队列通过回调要求更多数据并且我没有更多数据时,我开始倒计时缓冲区.如果缓冲区计数等于零,这意味着要播放的航班上只剩下一个缓冲区,则完成片刻播放时我会尝试停止音频队列.
-(void)decrementBufferUsedCount
{
if (buffersUsed>0) {
buffersUsed--;
printf("buffer on the queue %i\n",buffersUsed);
if (buffersUsed==0) {
NSLog(@"playback is finished\n");
// end playback
isPlayBackDone=YES;
double sampleRate = dataFormat.mSampleRate;
double bufferDuration = …Run Code Online (Sandbox Code Playgroud) 我需要使用Core Audio同时播放和录制.我真的不想使用AVFoundation API(AVAudioPlayer + AVAudioRecorder)这样做,因为我正在制作音乐应用程序,并且不会出现任何延迟问题.
我查看了Apple的以下源代码:
aurioTouch
MixerHost
我已经查看过以下帖子:
iOS:同步录制和播放的示例代码同时录制和播放
音频
我仍然不清楚如何使用Core Audio同时播放和录制相同的内容.任何有关如何实现这一目标的指示都将非常值得注意.任何示例源代码的任何指针也将有很大帮助.
ios ×5
core-audio ×4
iphone ×4
objective-c ×4
audio ×3
ios4 ×2
audioqueue ×1
audiosession ×1
audiotoolbox ×1
audiounit ×1
background ×1
cocoa ×1
multitasking ×1
record ×1
volume ×1
xcode ×1