トーンレンダリングバッファに1つのトーンを周波数で、もう1つに周波数/ 3で充填します。kLinearPCMFormatFlagIsNonInterleavedをクリアする方法、または設定しない方法
コードを実行すると、バッファがインターリーブされていないものとして出力が読み込まれるように見えます。実際それはcreateToneUnitで設定されています。 サウンドは左スピーカーでのみ再生されます。両方の周波数がバッファに書き込まれると、両方のトーンが左スピーカで再生されます。周波数がバッファに書き込まれていない場合、例えば、 leftON = 0、それらは再生されません。バッファ書き込みコードはOKのように見えます。
私はkLinearPCMFormatFlagIsNonInterleavedをcreateToneUnitに設定してはいけないと思うので、私はフラグを "クリア"しようとしました。私は何時間も書類を読んでいましたが、これを行う方法は決して見つかりませんでした。実験を行うと、アプリの起動時にクラッシュするだけでした。
kLinearPCMFormatFlagIsNonInterleavedをクリアするにはどうすればよいですか?
または、最初にkLinearPCMFormatFlagIsNonInterleavedを設定しないでください。 (streamFormat.mFormatFlagsをコメントアウトするとクラッシュも発生します)
おそらく、他の設定によってはインターリーブされた再生を妨げることがあります。あなたのケースでは
OSStatus RenderTone(
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
*)inRefCon;
float sampleRate = viewController->sampleRate;
float frequency = viewController->frequency;
// etc.
float theta_increment = 2.0 * M_PI * frequency /sampleRate;
float wave;
float theta2;
float wave2;
float theta_increment2 =0.3 * theta_increment;
const int channel = 0;
Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;
for (UInt32 frame = 0; frame < inNumberFrames;)
{
theta += theta_increment;
wave = sin(theta) * playVolume;
theta2 += theta_increment2;
wave2 = sin(theta2) * playVolume;
buffer[frame++] = wave * leftON; // leftON = 1 or 0
buffer[frame++] = wave2 * rightON; // rightON = 1 or 0
if (theta > 2.0 * M_PI)
{
theta -= 2.0 * M_PI;
}
}
// etc.
}
- (void)createToneUnit
{
AudioComponentDescription defaultOutputDescription;
defaultOutputDescription.componentType = kAudioUnitType_Output;
defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
defaultOutputDescription.componentFlags = 0;
defaultOutputDescription.componentFlagsMask = 0;
// etc.
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&input,
sizeof(input));
const int four_bytes_per_float = 4;
const int eight_bits_per_byte = 8;
AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = sampleRate;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags =
kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsNonInterleaved;
streamFormat.mBytesPerPacket = four_bytes_per_float;
streamFormat.mFramesPerPacket = 1;
streamFormat.mBytesPerFrame = four_bytes_per_float;
streamFormat.mChannelsPerFrame = 2; // 2= stereo/
streamFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
err = AudioUnitSetProperty (toneUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
}
質問100%に答えます。それは私がなぜこのことを考えるべきなのか尋ねる優雅な答えの一つです。 – user1251228