我正在使用核心音频(与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,但仍然没有成功。
给定[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的输出: