Еще один баг здесь:
ulong leftSampleIndex = IS_SHORT_NOT_EVEN( sampleNumber ) ? sampleNumber : sampleNumber + 1;
sample16 leftSample = buffer->getShort( leftSampleIndex );
ulong rightSampleIndex = IS_SHORT_EVEN( sampleNumber + 1 ) ? sampleNumber + 1 : sampleNumber;
sample16 rightSample = buffer->getShort( rightSampleIndex );
Помимо того что я раньше написал о перепутанных чёт/нечёт макросах, здесь у тебя оба семпла берутся из одного канала, тем самым неработает стерео - ошибка в неправильной логике условий.
Вот как у меня:
const uint32_t leftSampleIndex = ( sampleNumber & 1 ) ? sampleNumber + 1 : sampleNumber;
const int16_t leftSample = bfr->getShort( leftSampleIndex );
const uint32_t rightSampleIndex = ( ( sampleNumber + 1 ) & 1 ) ? sampleNumber + 1 : sampleNumber + 2;
const int16_t rightSample = bfr->getShort( rightSampleIndex );
Обрати внимание что если левый семпл берется sampleNumber+1 то правый должен быть sampleNumber
+2, а не sampleNumber+0.
//====================================
8192 звучит пугающе. Особенно если учесть что дискретизация 44кГц, а не 60fps как если бы графику считали. Однако 256 источников это чересчур, в игре в среднем 8-16 одновременно работающих в пространстве. Может быть в стратегиях или каких-нибудь arma их больше, но там нету такой качественной обработки. Получается 16 * 32 * 44100 = 22,579,200 вызовов микшера за секунду. Если бы обсчёт был на шейдерах то вполне потянуло бы, на цпу (без интегрированного гпу) скорей всего нет.
Однако нужно прежде всего сделать демку чтобы было от чего отталкиваться и примерно понимать насколько надо ускорить вычисления.
С другой стороны у меня же работал 1 источник с 32 кратным эхо и это грузило одно ядро меньше чем на половину, simd теоретически дает 4х в 32битном и 8х в 64битном приложении, на практике скорей будет в 3 и 6 раз быстрей. Так что вроде как в одно ядро может с десяток источников влезть.
К тому же например можно применять всякие хитрости, например если взять игру, разных типов источников не так уж и много, но бывает много однотипных источников, например падающие гильзы звенят. Их можно обрабатывать группой, например проигрывать звук каждой без эхо, а эхо добавить общее для всей группы - там на слух не разберешь какая из них звенит. И так далее, можно группировать по типу звука, по локализации, по громкости и т. д. и т. п.