Я делаю некоторую обработку звука с помощью float. Результат необходимо преобразовать обратно в образцы PCM, и я заметил, что приведение от float к int удивительно дорого.
Что еще более расстраивает, что мне нужно обрезать результат до диапазона короткого (от -32768 до 32767).
В то время как я обычно инстинктивно предполагаю, что это может быть обеспечено простым приведением значения типа float к short, в Java это терпит неудачу, поскольку на уровне байт-кода это приводит к F2I, за которым следует I2S. Так что вместо простого:
int sample = (short) flotVal;
Мне нужно было прибегнуть к этой ужасной последовательности:
int sample = (int) floatVal;
if (sample > 32767) {
sample = 32767;
} else if (sample < -32768) {
sample = -32768;
}
Есть ли более быстрый способ сделать это?
(около 6% общего времени выполнения, по-видимому, расходуется на приведение, в то время как на первый взгляд кажется, что 6% не так уж и много, и это поразительно, когда я считаю, что часть обработки включает в себя хороший кусок умножения матриц и IDCT )
РЕДАКТИРОВАТЬ Приведенный выше код приведения / отсечения находится (что неудивительно) в теле цикла, который считывает значения с плавающей точкой из float [] и помещает их в байт []. У меня есть набор тестов, который измеряет общее время выполнения в нескольких тестовых примерах (обработка около 200 МБ необработанных аудиоданных). 6% были получены из разницы времени выполнения, когда присвоение приведения "int sample = (int) floatVal" было заменено назначением индекса цикла для образца.
РЕДАКТИРОВАТЬ @leopoldkot: Мне известно об усечении в Java, как указано в исходном вопросе (F2I, последовательность байт-кода I2S). Я пробовал приводить только к коротким, потому что предполагал, что в Java есть байт-код F2S, чего, к сожалению, нет (изначально он был на фоне сборки 68K, где простой "fmove.w FP0, D0" сделал бы именно то, что я хотел) .