- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试从 iPod 库中的 MP3 中提取原始 PCM 样本,以便我可以播放歌曲并控制音高、速度和应用声音效果(例如过滤器)。我已经走上了 AVPlayer 和 AVAudioPlayer 的道路,它们根本不允许对播放进行太多控制。
下面的代码是我目前为止得到的。我现在不知道如何处理 while 循环中的 CMSampleBufferRef,因为我不知道要使用哪个框架来播放音频和应用此类效果。
知道实现此目标的最佳方法是什么吗?我已经查看了使用 AVAssetWriter 转换文件的情况,但这对我来说并不适用,因为这个过程太耗时了。当然,我可以直接将 PCM 样本读入内存进行播放,而不必先将它们写入磁盘吗?
注意:我知道下面的代码引用了项目中的 mp3,但我知道这种方法的工作方式与从 MPMediaPropertyAssetURL 中提取 NSURL 的效果相同
-(IBAction)loadTrack:(id)sender {
NSString *songPath = [[NSBundle mainBundle] pathForResource:@"Smooth_Sub Focus_192" ofType:@"mp3"];
NSURL *assetURL = [[NSURL alloc] initFileURLWithPath:songPath];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
NSError *assetError = nil;
AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset
error:&assetError] retain];
if (assetError) {
NSLog (@"Error: %@", assetError);
return;
}
AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
audioSettings: nil] retain];
if (![assetReader canAddOutput:assetReaderOutput]) {
NSLog (@"Incompatible Asser Reader Output");
return;
}
[assetReader addOutput: assetReaderOutput];
[assetReader startReading];
CMSampleBufferRef nextBuffer;
while (nextBuffer = [assetReaderOutput copyNextSampleBuffer]) {
/* What Do I Do Here? */
}
[assetReader release];
[assetReaderOutput release];
}
最佳答案
我正在自己的代码中做类似的事情。以下方法为 AVURLAsset 返回一些 NSData:
- (NSData *)extractDataForAsset:(AVURLAsset *)songAsset {
NSError * error = nil;
AVAssetReader * reader = [[AVAssetReader alloc] initWithAsset:songAsset error:&error];
AVAssetTrack * songTrack = [songAsset.tracks objectAtIndex:0];
AVAssetReaderTrackOutput * output = [[AVAssetReaderTrackOutput alloc] initWithTrack:songTrack outputSettings:nil];
[reader addOutput:output];
[output release];
NSMutableData * fullSongData = [[NSMutableData alloc] init];
[reader startReading];
while (reader.status == AVAssetReaderStatusReading){
AVAssetReaderTrackOutput * trackOutput = (AVAssetReaderTrackOutput *)[reader.outputs objectAtIndex:0];
CMSampleBufferRef sampleBufferRef = [trackOutput copyNextSampleBuffer];
if (sampleBufferRef){
CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBufferRef);
size_t length = CMBlockBufferGetDataLength(blockBufferRef);
UInt8 buffer[length];
CMBlockBufferCopyDataBytes(blockBufferRef, 0, length, buffer);
NSData * data = [[NSData alloc] initWithBytes:buffer length:length];
[fullSongData appendData:data];
[data release];
CMSampleBufferInvalidate(sampleBufferRef);
CFRelease(sampleBufferRef);
}
}
if (reader.status == AVAssetReaderStatusFailed || reader.status == AVAssetReaderStatusUnknown){
// Something went wrong. Handle it.
}
if (reader.status == AVAssetReaderStatusCompleted){
// You're done. It worked.
}
[reader release];
return [fullSongData autorelease];
}
我建议在后台线程上执行此操作,因为它很耗时。
这种方法的一个缺点是整首歌曲都加载到内存中,这当然是有限的。
关于iphone - 提取 iPod 库原始 PCM 样本并播放音效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4796643/
以下代码适用于某些 wav 文件,但对于其他文件,我得到“InvalidOperationException 未处理。Message=Sound API 仅支持播放 PCM wave 文件。” var
我正在尝试实现 AudioRecord (MIC) -> PCM -> AAC Encoder AAC -> PCM Decode -> AudioTrack?? (SPEAKER) 在 Andro
我想在我的 android 录音应用程序中实现使用 PCM 16 位和 PCM 8 位进行录音的可能性。我在将 byte[] PCM 16 位转换为 8 位时遇到问题,我尝试了不同的方法,但是录音的大
如何将无符号的 8 位 PCM 流 (0-255) 转换为有符号的 8 位 PCM 流 (-128-127)。从每个无符号字节中减去 128 让 0 变成 -128 和 255 变成 127 这么简单
问题与此有关 pydub-Issue .他们告诉我错误信息与 pyaudio 有关。 #!/usr/bin/env python3 import pydub, pydub.playback wav =
我无法在 C++ 中的 16 位缩放 PCM 数据和浮点 PCM 数据之间进行转换。我认为我必须接近,因为输出音频有点类似于我的预期,但它是失真的。 我这样做的原因是因为我在浏览器中运行 ScummV
从this question开始让我了解如何去交错 16 位 PCM 数据的左右声道。 我现在的问题是,如何将 8 位 PCM 解交错并“拉伸(stretch)”为 16 位值 最佳答案 16 位 P
我想添加一些噪音 44100 Hz 2 channel 16 bit interleaved PCM 我正在生成 1 秒的 440Hz 噪声并将其存储在噪声缓冲区中: #define SAMPLING
我是这里的新手。 我想知道任何工具/快速方法来转换具有 3 字节 PCM 样本的 24 位 PCM 原始( headless )文件, 成一个 32 位 PCM 原始文件,每个样本有 4 个字节,4
我已将已签名的单声道 16 位 PCM 音频样本存储在 SInt16 缓冲区中,我正在尝试将它们转换为存储在 UInt8 缓冲区中的未签名的单声道 8 位 PCM 样本。我编写了以下基本工作代码: f
我正在使用 libao 和 libsndfile 来读取和播放音频。我想通过将一个 channel 复制为两个来将单声道流转换为立体声流。此测试代码将正确播放立体声剪辑,但会非常快速和高音播放单声道剪
我正在致力于捕获音频并将其流式传输到 RTMP 服务器。我在 MacOS 下工作(在 Xcode 中),因此为了捕获音频样本缓冲区,我使用 AVFoundation 框架。但对于编码和流媒体,我需要使
我正在尝试从文本到语音接口(interface) (MaryTTS) 获取音频流并将其流式传输到 SIP RTP session 中(使用 Peers)。 同行想要 SoundSource流式传输音频
我已将录制的音频原始 PCM 保存到文件 rxrawpcm.pcm 中,之后我尝试播放 pcm 文件但无法播放录制的 PCM?我没有听到录音,只听到嗡嗡声 配置 AudioRecorder 和 Aud
我有一些原始 PCM 音频文件。我可以成功地从这些文件中读取字节流,并通过接受 PCM 数据作为输入的音频播放机制来播放它们。 当我从这些文件中读取数据时,我将其存储在字节[]中。这些轨道具有相同的大
我正在使用 C++ 进行声波模拟,我从 wav 文件中获取原始 PCM 数据并对其应用一些计算然后我想实时播放它我还想在用户更改一些时重新计算这些数据模拟中的值(如他的位置)。 我尝试了 Portau
我想在 Discord 语音 channel 中录制音频并使用 Discord 机器人将其保存到文件中。 我每 20 毫秒接收一次音频作为 pcm 编码的字节 [],我想将其保存到文件中。MP3 是首
我正在使用 AudioRecord 类来分析麦克风中的原始 pcm 字节。 所以这很好用。现在我需要将 pcm 字节转换为分贝。 我有一个公式可以将 Pa 中的声压转换为 db。 db = 20 *
我使用 oboe在我的 ndk 库中播放声音,我使用 OpenSL with Android extensions将 wav 文件解码为 PCM。解码后的签名 16 位 PCM 存储在内存中 ( st
我可以访问 PCM 音频缓冲区的音频流。我应该清楚我无权访问音频文件。我只能访问 4096 字节的音频数据 block 流。 PCM 缓冲区采用以下格式: PCM 国际 16 小端 两个 channe
我是一名优秀的程序员,十分优秀!