Если не боитесь читать исходники, возьмите libmodplug и посмотрите, как это сделано у них. Принцип вам
MTonly уже описал.
То, что вы делали — «это слишком». Если брать каждый второй сэмпл получается примитивный частный случай (но совершенно правильный с точки зрения теории!) ресемплинга «на октаву выше». Не немного, сразу на октаву, т.к. частота вырастает сразу вдвое.
Если нужно не вдвое, ресемплинг нужно делать не так. В частности, брать не каждый второй, а допустим при проигрывании каждых очередных 100 отсчётов получать их из 101 исходного отсчёта. Таким образом вы сделаете звук чуть-чуть выше. Примитивный вариант для вас будет — линейная интерполяция: отсчёты расположены равномерно, но «решётки» не совпадают. Вычисляете, с какими весами должны входить два ближайших отсчёта.
Пример:
Пусть отсчёты PCM будут 15 123 53 234 54 52 35 151… Мы хотим сыграть их на квинту выше, т.е. для каждых трёх исходных мы должны воспроизвести два.
тогда на выходе будет:
15, (125+53)/2, 234, (54+52)/2, 35, и так далее. Я здесь «промежуточные» отсчёты, которые находились в тех точках, в которых в оригинале ничего не было, вычисляю при помощи линейной интерполяции. Поскольку новые отсчёты лежат точно посередине, два «соседних» входят с одинаковыми весами.
Другой пример с этой же последовательностью: мы хотим сделать из этих восьми отсчётов семь. На выходе:
15, (123*5+53*1)/6, (53*4+234*2)/6, (234*3+54*3)/6, (54*2+52*4)/6, (52*1+35*5)/6, 151,…
Или же, сдвиг на a=0.992:
15, 123*(1-a)+53*a, 53*(1-2a)+234*2a,… — осталось только научиться правильно обрабатывать момент, когда n*a становится больше единицы.
Стоит нарисовать «временнУю диаграмму» для того и другого количества отсчётов, а потом посмотреть, что и как вычислять.
Для аккуратной интерполяции есть более продвинутые алгоритмы, в частности, фильтры FIR (finite impulse response, КИХ, конечная импульсная характеристика) — они будут давать меньше «призвуков» при таком изменении тона.
А потом вы забьёте на реализацию этого самостоятельно и начнёте использовать библиотеку rubberband :)