gpt4 book ai didi

ios - 如何从 iOS 中的十六进制/二进制(原始数据)值生成音频文件?

转载 作者:行者123 更新时间:2023-11-28 12:05:27 25 4
gpt4 key购买 nike

我正在从事 BLE 项目,其中录音机硬件连续流式传输数据并发送到 iOS 应用程序。从 iOS 应用程序端,我需要读取传输的数据。

硬件向 iOS 应用程序发送 HEX 数据,我们需要创建 .mp3/.wav 文件

有没有人有想法从二进制/十六进制输入数据创建音频文件?

注意:我必须使用原始数据(十六进制)来创建音频文件。

谢谢

最佳答案

从你的问题中不清楚数据是如何进来的,但我现在假设你定期有一个线性 PCM 数据的 Data 作为你想要附加的有符号整数.如果是其他格式,则必须更改设置。这些都是通用的东西;您几乎肯定必须根据您的具体问题修改它。

(大部分代码基于 Create a silent audio CMSampleBufferRef )

首先你需要一个作家:

let writer = try AVAssetWriter(outputURL: outputURL, fileType: .wav)

然后你需要知道你的数据是如何格式化的(这是悄悄地假设数据是帧大小的倍数;如果这不是真的,你需要跟踪部分帧):

let numChannels = 1
let sampleRate = 44100
let bytesPerFrame = MemoryLayout<Int16>.size * numChannels
let frames = data.count / bytesPerFrame
let duration = Double(frames) / Double(sampleRate)
let blockSize = frames * bytesPerFrame

然后你需要知道当前帧是什么。这将随着时间的推移而更新。

var currentFrame: Int64 = 0

现在您需要对您的数据进行描述:

var asbd = AudioStreamBasicDescription(
mSampleRate: Float64(sampleRate),
mFormatID: kAudioFormatLinearPCM,
mFormatFlags: kLinearPCMFormatFlagIsSignedInteger,
mBytesPerPacket: UInt32(bytesPerFrame),
mFramesPerPacket: 1,
mBytesPerFrame: UInt32(bytesPerFrame),
mChannelsPerFrame: UInt32(numChannels),
mBitsPerChannel: UInt32(MemoryLayout<Int16>.size*8),
mReserved: 0
)

var formatDesc: CMAudioFormatDescription?
status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &asbd, 0, nil, 0, nil, nil, &formatDesc)
assert(status == noErr)

然后创建您的输入适配器并将其添加到编写器

let settings:[String : Any] = [ AVFormatIDKey : kAudioFormatLinearPCM,
AVNumberOfChannelsKey : numChannels,
AVSampleRateKey : sampleRate ]
let input = AVAssetWriterInput(mediaType: .audio, outputSettings: settings, sourceFormatHint: formatDesc)

writer.add(input)

这就是所有的一次性设置,是时候启动编写器了:

writer.startWriting()
writer.startSession(atSourceTime: kCMTimeZero)

如果您的所有数据大小相同,您可以创建一个可重复使用的缓冲区(或者您可以每次都创建一个新缓冲区):

var block: CMBlockBuffer?
var status = CMBlockBufferCreateWithMemoryBlock(
kCFAllocatorDefault,
nil,
blockSize, // blockLength
nil, // blockAllocator
nil, // customBlockSource
0, // offsetToData
blockSize, // dataLength
0, // flags
&block
)
assert(status == kCMBlockBufferNoErr)

当数据进来时,将其复制到缓冲区中:

status = CMBlockBufferReplaceDataBytes(&inputData, block!, 0, blockSize)
assert(status == kCMBlockBufferNoErr)

现在从缓冲区创建一个示例缓冲区并将其附加到编写器输入:

var sampleBuffer: CMSampleBuffer?

status = CMAudioSampleBufferCreateReadyWithPacketDescriptions(
kCFAllocatorDefault,
block, // dataBuffer
formatDesc!,
frames, // numSamples
CMTimeMake(currentFrame, Int32(sampleRate)), // sbufPTS
nil, // packetDescriptions
&sampleBuffer
)
assert(status == noErr)

input.append(sampleBuffer!)

当一切都完成后,完成编写器,你就完成了:

input.markAsFinished()
writer.finishWriting{}

关于ios - 如何从 iOS 中的十六进制/二进制(原始数据)值生成音频文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49408602/

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