Я создал простой генератор сигналов, который подключен к AUGraph. Я повторно использовал пример кода от Apple, чтобы установить AudioStreamBasicDescription, как это
void SetCanonical(UInt32 nChannels, bool interleaved)
// note: leaves sample rate untouched
{
mFormatID = kAudioFormatLinearPCM;
int sampleSize = SizeOf32(AudioSampleType);
mFormatFlags = kAudioFormatFlagsCanonical;
mBitsPerChannel = 8 * sampleSize;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved)
mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
else {
mBytesPerPacket = mBytesPerFrame = sampleSize;
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
В моем классе я называю эту функцию
mClientFormat.SetCanonical(2, true);
mClientFormat.mSampleRate = kSampleRate;
в то время как частота дискретизации
#define kSampleRate 44100.0f;
Другие настройки также взяты из примера кода
// output unit
CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple);
// iPodEQ unit
CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple);
// multichannel mixer unit
CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple);
Все работает нормально, но проблема в том, что я не получаю стереозвук, и моя функция обратного вызова не работает (плохой доступ), когда я пытаюсь достичь второго буфера
Float32 *bufferLeft = (Float32 *)ioData->mBuffers[0].mData;
Float32 *bufferRight = (Float32 *)ioData->mBuffers[1].mData;
// Generate the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
{
switch (generator.soundType) {
case 0: //Sine
bufferLeft[frame] = sinf(thetaLeft) * amplitude;
bufferRight[frame] = sinf(thetaRight) * amplitude;
break;
Кажется, я получаю моно вместо стерео. Указатель bufferRight пуст, но не знаю почему.
Любая помощь будет оценена.
Я вижу две возможные ошибки. Во-первых, как указал @invalidname, запись в стерео режиме, вероятно, не будет работать на монофоническом устройстве, таком как iPhone. Ну, это может сработать, но если это сработает, вы все равно просто вернете двойные монофонические стереопотоки, так зачем беспокоиться? Вы также можете настроить свой поток для работы в режиме моно и сэкономить ресурсы ЦП.
Вторая проблема, вероятно, является источником искажения звука. Флаги формата описания вашего потока должны быть:
kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked
Кроме того, не забудьте установить флаг mReserved в 0. Хотя значение этого флага, вероятно, игнорируется, не повредит явно установить его в 0 просто для уверенности.
Редактировать: еще один более общий совет по отладке звука на iPhone — если вы получаете искажения, обрезки или другие странные эффекты, возьмите полезную информацию с вашего телефона и посмотрите на запись в волновом редакторе. Возможность уменьшить масштаб и посмотреть на отдельные образцы даст вам много подсказок о том, что происходит не так.
Для этого вам нужно открыть окно «Органайзер», нажать на свой телефон, а затем развернуть маленькую стрелку рядом с вашим приложением (там же, где вы обычно удаляете его). Теперь вы увидите небольшую стрелку, указывающую вниз, и если вы щелкнете по ней, Xcode скопирует данные из вашего приложения в другое место на вашем жестком диске. Если вы записываете свои записи на диск, вы найдете файлы, извлеченные здесь.
ссылка от ссылка на сайт
Я предполагаю, что проблема в том, что вы указываете чередующийся формат, но затем получаете доступ к буферам, как если бы они не чередовались в вашем обратном вызове ввода-вывода. ioData-> mBuffers [1] недопустим, поскольку все данные, как левого, так и правого каналов, чередуются в ioData-> mBuffers [0] .mData. Проверьте ioData-> mNumberBuffers. Я предполагаю, что он установлен в 1. Кроме того, убедитесь, что ioData-> mBuffers [0] .mNumberChannels установлен в 2, что указывает на чередующиеся данные.
Также ознакомьтесь с классами Core Audio Public Utility, чтобы помочь с такими вещами, как настройка форматов. Делает это намного проще. Ваш код для настройки формата может быть уменьшен до одной строки, и вы будете более уверены в его правильности (хотя для меня ваш формат выглядит настроенным правильно — если то, что вы хотите, чередуется с 16-битным int):
CAStreamBasicDescription myFormat(44100.0, 2, CAStreamBasicDescription::kPCMFormatInt16, true)
Apple раньше упаковывала эти классы в SDK, который был установлен с Xcode, но теперь вам нужно скачать их здесь: https://developer.apple.com/library/mac/samplecode/CoreAudioUtilityClasses/Introduction/Intro.html
В любом случае, похоже, что самое простое решение — просто изменить формат без чередования. Итак, в вашем коде: mClientFormat.SetCanonical (2, false);