- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想为 iPhone 构建一个合成器。据我了解,可以为 iPhone 使用自定义音频单元。乍一看,这听起来很有希望,因为有大量的音频单元编程资源可用。然而,在 iPhone 上使用自定义音频单元似乎有点棘手(请参阅:http://lists.apple.com/archives/Coreaudio-api/2008/Nov/msg00262.html)
这似乎是很多人都必须做的事情,但是简单地在谷歌上搜索“iphone 音频合成”并不会出现任何类似于简单易用的教程或推荐工具包的内容。
那么,这里有人有在 iPhone 上合成声音的经验吗?自定义音频单元是可行的方法,还是我应该考虑另一种更简单的方法?
最佳答案
我也在调查这个。我认为 AudioQueue API 可能是正确的选择。
据我所知,似乎工作正常。
文件:BleepMachine.h
//
// BleepMachine.h
// WgHeroPrototype
//
// Created by Andy Buchanan on 05/01/2010.
// Copyright 2010 Andy Buchanan. All rights reserved.
//
#include <AudioToolbox/AudioToolbox.h>
// Class to implement sound playback using the AudioQueue API's
// Currently just supports playing two sine wave tones, one per
// stereo channel. The sound data is liitle-endian signed 16-bit @ 44.1KHz
//
class BleepMachine
{
static void staticQueueCallback( void* userData, AudioQueueRef outAQ, AudioQueueBufferRef outBuffer )
{
BleepMachine* pThis = reinterpret_cast<BleepMachine*> ( userData );
pThis->queueCallback( outAQ, outBuffer );
}
void queueCallback( AudioQueueRef outAQ, AudioQueueBufferRef outBuffer );
AudioStreamBasicDescription m_outFormat;
AudioQueueRef m_outAQ;
enum
{
kBufferSizeInFrames = 512,
kNumBuffers = 4,
kSampleRate = 44100,
};
AudioQueueBufferRef m_buffers[kNumBuffers];
bool m_isInitialised;
struct Wave
{
Wave(): volume(1.f), phase(0.f), frequency(0.f), fStep(0.f) {}
float volume;
float phase;
float frequency;
float fStep;
};
enum
{
kLeftWave = 0,
kRightWave = 1,
kNumWaves,
};
Wave m_waves[kNumWaves];
public:
BleepMachine();
~BleepMachine();
bool Initialise();
void Shutdown();
bool Start();
bool Stop();
bool SetWave( int id, float frequency, float volume );
};
// Notes by name. Integer value is number of semitones above A.
enum Note
{
A = 0,
Asharp,
B,
C,
Csharp,
D,
Dsharp,
E,
F,
Fsharp,
G,
Gsharp,
Bflat = Asharp,
Dflat = Csharp,
Eflat = Dsharp,
Gflat = Fsharp,
Aflat = Gsharp,
};
// Helper function calculates fundamental frequency for a given note
float CalculateFrequencyFromNote( SInt32 semiTones, SInt32 octave=4 );
float CalculateFrequencyFromMIDINote( SInt32 midiNoteNumber );
文件:BleepMachine.mm
//
// BleepMachine.mm
// WgHeroPrototype
//
// Created by Andy Buchanan on 05/01/2010.
// Copyright 2010 Andy Buchanan. All rights reserved.
//
#include "BleepMachine.h"
void BleepMachine::queueCallback( AudioQueueRef outAQ, AudioQueueBufferRef outBuffer )
{
// Render the wave
// AudioQueueBufferRef is considered "opaque", but it's a reference to
// an AudioQueueBuffer which is not.
// All the samples manipulate this, so I'm not quite sure what they mean by opaque
// saying....
SInt16* coreAudioBuffer = (SInt16*)outBuffer->mAudioData;
// Specify how many bytes we're providing
outBuffer->mAudioDataByteSize = kBufferSizeInFrames * m_outFormat.mBytesPerFrame;
// Generate the sine waves to Signed 16-Bit Stero interleaved ( Little Endian )
float volumeL = m_waves[kLeftWave].volume;
float volumeR = m_waves[kRightWave].volume;
float phaseL = m_waves[kLeftWave].phase;
float phaseR = m_waves[kRightWave].phase;
float fStepL = m_waves[kLeftWave].fStep;
float fStepR = m_waves[kRightWave].fStep;
for( int s=0; s<kBufferSizeInFrames*2; s+=2 )
{
float sampleL = ( volumeL * sinf( phaseL ) );
float sampleR = ( volumeR * sinf( phaseR ) );
short sampleIL = (int)(sampleL * 32767.0);
short sampleIR = (int)(sampleR * 32767.0);
coreAudioBuffer[s] = sampleIL;
coreAudioBuffer[s+1] = sampleIR;
phaseL += fStepL;
phaseR += fStepR;
}
m_waves[kLeftWave].phase = fmodf( phaseL, 2 * M_PI ); // Take modulus to preserve precision
m_waves[kRightWave].phase = fmodf( phaseR, 2 * M_PI );
// Enqueue the buffer
AudioQueueEnqueueBuffer( m_outAQ, outBuffer, 0, NULL );
}
bool BleepMachine::SetWave( int id, float frequency, float volume )
{
if ( ( id < kLeftWave ) || ( id >= kNumWaves ) ) return false;
Wave& wave = m_waves[ id ];
wave.volume = volume;
wave.frequency = frequency;
wave.fStep = 2 * M_PI * frequency / kSampleRate;
return true;
}
bool BleepMachine::Initialise()
{
m_outFormat.mSampleRate = kSampleRate;
m_outFormat.mFormatID = kAudioFormatLinearPCM;
m_outFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
m_outFormat.mFramesPerPacket = 1;
m_outFormat.mChannelsPerFrame = 2;
m_outFormat.mBytesPerPacket = m_outFormat.mBytesPerFrame = sizeof(UInt16) * 2;
m_outFormat.mBitsPerChannel = 16;
m_outFormat.mReserved = 0;
OSStatus result = AudioQueueNewOutput(
&m_outFormat,
BleepMachine::staticQueueCallback,
this,
NULL,
NULL,
0,
&m_outAQ
);
if ( result < 0 )
{
printf( "ERROR: %d\n", (int)result );
return false;
}
// Allocate buffers for the audio
UInt32 bufferSizeBytes = kBufferSizeInFrames * m_outFormat.mBytesPerFrame;
for ( int buf=0; buf<kNumBuffers; buf++ )
{
OSStatus result = AudioQueueAllocateBuffer( m_outAQ, bufferSizeBytes, &m_buffers[ buf ] );
if ( result )
{
printf( "ERROR: %d\n", (int)result );
return false;
}
// Prime the buffers
queueCallback( m_outAQ, m_buffers[ buf ] );
}
m_isInitialised = true;
return true;
}
void BleepMachine::Shutdown()
{
Stop();
if ( m_outAQ )
{
// AudioQueueDispose also chucks any audio buffers it has
AudioQueueDispose( m_outAQ, true );
}
m_isInitialised = false;
}
BleepMachine::BleepMachine()
: m_isInitialised(false), m_outAQ(0)
{
for ( int buf=0; buf<kNumBuffers; buf++ )
{
m_buffers[ buf ] = NULL;
}
}
BleepMachine::~BleepMachine()
{
Shutdown();
}
bool BleepMachine::Start()
{
OSStatus result = AudioQueueSetParameter( m_outAQ, kAudioQueueParam_Volume, 1.0 );
if ( result ) printf( "ERROR: %d\n", (int)result );
// Start the queue
result = AudioQueueStart( m_outAQ, NULL );
if ( result ) printf( "ERROR: %d\n", (int)result );
return true;
}
bool BleepMachine::Stop()
{
OSStatus result = AudioQueueStop( m_outAQ, true );
if ( result ) printf( "ERROR: %d\n", (int)result );
return true;
}
// A (A4=440)
// A# f(n)=2^(n/12) * r
// B where n = number of semitones
// C and r is the root frequency e.g. 440
// C#
// D frq -> MIDI note number
// D# p = 69 + 12 x log2(f/440)
// E
// F
// F#
// G
// G#
//
// MIDI Note ref: http://www.phys.unsw.edu.au/jw/notes.html
//
// MIDI Node numbers:
// A3 57
// A#3 58
// B3 59
// C4 60 <--
// C#4 61
// D4 62
// D#4 63
// E4 64
// F4 65
// F#4 66
// G4 67
// G#4 68
// A4 69 <--
// A#4 70
// B4 71
// C5 72
float CalculateFrequencyFromNote( SInt32 semiTones, SInt32 octave )
{
semiTones += ( 12 * (octave-4) );
float root = 440.f;
float fn = powf( 2.f, (float)semiTones/12.f ) * root;
return fn;
}
float CalculateFrequencyFromMIDINote( SInt32 midiNoteNumber )
{
SInt32 semiTones = midiNoteNumber - 69;
return CalculateFrequencyFromNote( semiTones, 4 );
}
//for ( SInt32 midiNote=21; midiNote<=108; ++midiNote )
//{
// printf( "MIDI Note %d: %f Hz \n",(int)midiNote,CalculateFrequencyFromMIDINote( midiNote ) );
//}
更新:基本使用信息
初始化。在接近开始的地方,我在代码中使用 initFromNib:
m_bleepMachine = new BleepMachine;
m_bleepMachine->Initialise();
m_bleepMachine->Start();
现在声音播放正在运行,但产生静音。
在您的代码中,当您想要更改音调生成时调用此函数
m_bleepMachine->SetWave( ch, frq, vol );
程序终止时
delete m_bleepMachine;
关于iphone - iPhone 上的音频合成从哪里开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2067267/
如果我使用 NSUserDefaults 存储应用程序的设置,是否有任何方法可以使我的应用程序的设置“隐藏”,以免显示在 iPhone 上的常规设置应用程序中?我知道还有其他工具,例如 mySetti
我按照该网站的教程进行操作: http://theappleblog.com/2008/08/04/tutorial-build-a-simple-rss-reader-for-iphone/ 为了制
我通过 localisableString 和仅适用于 NSLocale 方法的不同 xib 更改 iPhone 的语言来完成本地化,但应用程序的要求是通过更改应用程序设置 View 中的语言来本地化
我试图弄清楚 iPhone 是否可以通过无线或蓝牙连接到另一台非 iPhone 设备,但发现了相互冲突的信息。我发现的大部分内容都是在 SDK 3.0 版本发布之前发现的,当时这肯定是不可能的。查看堆
This question already has answers here: Closed 7 years ago. Possible Duplicate: How to detect iPhone
当我在模拟器上运行我的应用程序时,每次都会生成白色的空白屏幕。但是当我在底部黑色 iPhone 按钮退出应用程序后,重新进入应用程序后 View 将可见。然后应用程序照常运行。 但是当我将它加载到我的
我的意思是两台 iPhone 设备应该通过蓝牙或 WiFi 连接,并且一台设备的 UI 应该扩展到另一台 iPhone 设备(不共享屏幕)。我们有办法在 iOS 中执行此操作吗? 最佳答案 Bump
如何通过宏检测设备型号?我使用过类似的东西,但模拟器上的结果总是 IS_IPHONE_5 #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInt
我目前有一个应用程序要求用户维护 VPN 隧道。加载时我检查 VPN 隧道是否可用。 我想知道是否有任何方法可以显示 UIAlertView,单击“确定”后,用户将进入 iPhone 主设置屏幕,以便
我正在开发一个 iPhone 客户端应用程序,它允许用户对各种服务进行评分。无需注册或登录。 要求是用户不能重复对服务进行评分(尽管可以更改其评分)。从目前的情况来看,该应用程序可以被删除、重新安装,
比如说,我点击一个 iphone 应用程序图标,启动时它将创建一个 .app 文件。那么是否可以从该应用程序调用另一个 iphone 应用程序。或者我们可以在该 .app 文件中执行一些操作,例如它将
真的有可能让iPhone静音模式独立于iPhone App吗? 这个应用程序"Talking Carl"让我很困惑。我的 iPhone 处于静音模式。每当我打开这个应用程序时。应用程序声音处于开启模式
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
如果我想编写一些自定义 iPhone 应用程序,但不一定通过 App Store 分发它们,是否可以在不加入 iPhone 开发者计划的情况下实现? 假设我只是想为自己编写一些小实用程序并将其放入我的
人们对 Unity 或 Torque Engine 等游戏引擎有何看法和/或体验?如果您是 iPhone 游戏开发新手,是否值得学习其中一种引擎?这些引擎生成的应用程序与使用 sdk 的 native
您能否在未安装 XCode 开发工具的计算机上分发 iPhone 应用程序以在 iPhone 模拟器中进行测试?可以直接在电脑上安装模拟器进行测试吗? 我有一组测试人员,他们不是开发人员,除了能够运行
我想在我的越狱设备上构建并安装我的应用程序,而无需支付 iPhone 开发者计划所需的 99 美元。我有 Rock 和 Cydia...最简单的方法是什么(如果可能的话)? 谢谢。 最佳答案 这是一个
我想测试一个网站,看看它如何与 iPhone 配合使用,但我没有 iPhone 或 iPod touch。有没有一种方法可以让我在不拥有网站的情况下测试网站的运行情况? 我真正想要的是修复 Stack
简单地说;我的 99 美元能给我带来什么我无法免费获得的东西? 好吧,好吧,听起来是个愚蠢的问题,但苹果网站对我来说并不清楚。 我的预感是,您可以在 99 岁时向应用程序商店提交应用程序,但您可以免费
我是一名注册的 iOS 开发人员。如何将我的 iPhone 应用程序转移到我的个人 iPhone? 最佳答案 用于测试?只需选择您的设备而不是模拟器即可。 关于iphone - 如何将我的 iPhon
我是一名优秀的程序员,十分优秀!