当前位置: 首页 > 知识库问答 >
问题:

与音频流格式和核心音频数据类型的混淆

公冶桐
2023-03-14

我正在使用核心音频(与swift包装)播放一些音频样本(一个简短的刺激,其中记录一个冲动)。我坚持使用核心音频,而不是更新的AVFoundation,因为我需要一些严格的定时和多设备输入,更新的框架还没有涵盖(我通过苹果代码请求他们告诉我必须使用核心音频)。

我现在创建了一个非常简单的正弦波,使用:

func createSine()->[Float]{
    var timeArray = makeArray(from: ((1.0/Float(sampleRate))*((-0.5)*Float(kernelLength))), to: ((1.0/Float(sampleRate))*((0.5)*Float(kernelLength))), increment: 1/sampleRate)
    var sineArray = Array(repeating:0, count: timeArray.count)

    for i in 0..<timeArray.count {
            let x = 2 * Float.pi * 1000 * testTimeArray[i]
            sineArray[i] = cos(x)
    }
}

如果我把它写到一个wav文件并回放,音调就会按预期的方式创建。

然而,我实际上想在应用程序中触发这个声音。我已经设置了我的AUGRAPE,并用音频单元填充了它。我已经创建了一个AURenderCallback,它在混频器的输入上被调用。每次,这个输入都需要它调用这个回调函数的信号。

let genCallback: AURenderCallback = { (
    inRefCon,
    ioActionFlags,
    inTimeStamp,
    inBusNumber,
    frameCount,
    ioData) -> OSStatus in

        let audioObject = unsafeBitCast(inRefCon, to: AudioEngine.self)

        for buffer in UnsafeMutableAudioBufferListPointer(ioData!) {
            var frames = buffer.mData!.assumingMemoryBound(to: Float.self)

            var j = 0

             for i in stride(from: 0, to: Int(frameCount), by: 2) {

                frames[i] = Float((audioObject.Stimulus[j + audioObject.stimulusReadIndex]))

                j += 1

            }

            audioObject.stimulusReadIndex += Int(frameCount/2)
        }
    }

   return noErr;
}

其中AudioObject.Instruction是我的SineArray,而AudioObject.InstrucusReadIndex只是一个计数器,用来记住数组中已读取的内容。

如果我查看mixer单元的AudioStreamBasicDescription(因为这是在调用render回调,所以我有以下内容:

var audioFormat = AudioStreamBasicDescription()
    audioFormat.mSampleRate            = 44100.00;
    audioFormat.mFormatID            = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags        = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
    audioFormat.mFramesPerPacket    = 1;
    audioFormat.mChannelsPerFrame    = 2;
    audioFormat.mBitsPerChannel        = 16;
    audioFormat.mBytesPerPacket        = 4;
    audioFormat.mBytesPerFrame        = 4;
    audioFormat.mReserved             = 0;

  status = AudioUnitSetProperty(mixerUnit!,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  1,
                                  &stimFormat,
                                  UInt32(MemoryLayout<AudioStreamBasicDescription>.size));
    checkStatus(status: status!);

所以这告诉了我一些事情。它需要两个通道,并且是交织的(因为非交织标志不存在)。在回调函数中,我将帧间隔2以只在第一个通道中填充示例。如果我从1开始,并回放音频被写入并回放到右手边。

采样率是正确的,但是比特率是16(Float不是),我可以看到有一个标志'is signedinteger',所以这是一个不同的格式。

for i in 0..<sineArray.count{
       sineArray[i] =  Int16.init((32767 * sweepSamples[i]))
    }

我看不出如何以core audio希望看到的格式表示此数据。我尝试将格式标志更改为kAudioFormatFlagIsFloat,但仍然没有成功。

共有1个答案

龚铭
2023-03-14

给定[Float]数据,您可能希望使用kAudioFormatFlagIsSignedInteger和32位(每个数据包和帧8字节),而不是kAudioFormatFlagIsFloat和每个通道16位。

请注意,对于所有最新的iOS设备,本机音频格式是32位浮点数,而不是16位int数,使用本机(硬件?)采样率是48000,而不是44100。

此外,请注意,苹果建议不要在音频回调上下文中使用Swift(参见2017或2018年WWDC关于音频的会话),因此您的音频单元渲染回调可能应该调用一个C函数来完成所有工作(任何涉及ioData或inRefCon的工作)。

您可能还需要检查以确保数组索引没有超出数组边界。

 类似资料:
  • 这里我有记录音频流文件的代码。问题是我想保存这个文件与正确的文件扩展名(主要是. mp3和. aac)。我该如何实现这一点?

  • 我想创建一个实时正弦发生器使用苹果核心音频框架。我想做低水平,这样我就可以学习和理解基本原理。 通过使用VSYNC,我可以将循环降低到60 fps。时间不是很紧,但相当稳定。我也有一些代码来手动使用马赫计时,这甚至更不精确。为了可读性我把它省略了。不使用VSYNC或使用马赫定时来获得每秒60次迭代也会造成音频故障。 定时日志: 这里重要的是函数。它每秒被调用60次,并传递给它一个包含基本信息的结构

  • 本文向大家介绍你知道有哪些常见的视频(音频)编码格式和视频(音频)格式吗?相关面试题,主要包含被问及你知道有哪些常见的视频(音频)编码格式和视频(音频)格式吗?时的应答技巧和注意事项,需要的朋友参考一下 视频:.ogg .mov .webp .avi .rmvb .mp4 音频:.mp3 .wav 只能想到这么多 webp?不是图片格式吗

  • 问题内容: 我在转换WAV文件的音频格式时遇到麻烦。 我正在从麦克风录制声音,并且声音以以下格式录制:PCM_SIGNED 44100.0 Hz,16位,单声道,2字节/帧 我想将上述格式转换为ULAW 8000.0 Hz,8位,单声道,1字节/帧 我正在使用以下代码, 我收到以下错误, java.lang.IllegalArgumentException:不支持的转换:ULAW 8000.0 H

  • 问题内容: 我正在设计一个简单的调谐器,所以我的目标是显示音符名称(A,B,F#)以及理论声音和实际输入之间的 距离( 以分为单位)。 我是音频和信号处理的新手,所以我做了一些研究,发现 了一个 叫做快速傅立叶变换 的东西 ,它可以分析字节并给我频率。另外,我发现了一些Java库,例如通用数学和JTransforms,所以我不会自己编写硬代码。 我相信就这样,因为每个范围的频率都可以以相同的气质直

  • 我正在尝试使用ffmpeg将视频(H.264)和音频(PCM_S16LE,无压缩)混合到MPEG传输流中。视频显示良好。但是,音频流无法播放。ff探针显示的音频流是AAC,这显然不是我的意图。所以我在添加音频流时一定做错了什么。知道如何纠正吗? 这是我添加音频流的代码: 以下是ffprobe的输出: