...например, чтобы преобразовать из float в unsigned 16 необходимо:
1. домножить значение float на 32767 с округлением до целого (чтобы получить значение в диапазоне от -32767 до 32767)
2. прибавить к результату 32767 (чтобы получить беззнаковое 0 - 65534)
p.s.
забыл добавить, необходимо учитывать так же порядок следования бит (big-endian или little-endian) для правильной интерпретации.
Нет. Ну так это то понятно, вопрос в том, что мне нужно float 32b преобразовать к float 16b (прости господи за ересь). Т.е. имеется ввиду что для воспроизведения QAudioOutput требует 2 байтный float, а не 2-байтный int. Как же объяснить-то?
Значит так:
QAudioFormat f;
f.setFrequency(8000);
f.setChannels(1);
f.setSampleType(QAudioFormat::Float);
f.setSampleSize(16);
f.setByteOrder(QAudioFormat::LittleEndian);
f.setCodec("audio/pcm");
QByteArray arr;
QBuffer b(&arr);
b.open(QIODevice::WriteOnly);
QAudioDeviceInfo devInfo = QAudioDeviceInfo::defaultInputDevice();
....
audio = new QAudioInput(*devInfo, *f, this);
audio.start(&b);
...
audio.stop();
В результате в arr будут лежать данные, прочитанные с микрофона. Параметры данных:
1. Данные кодируются 16 битами на отсчет
2. Контейнером для 16 бит является float
Далее мне нужно прочитать данные из arr в массив отсчетов (дабы эти отсчеты потом менять - фильтовать и т.д.)
Так вот. Так прочитать не получится:
QBuffer b(&arr);
QDataStream str(&b);
b.open(QIODevice::ReadOnly);
float f;
str>>f;
ибо автоматически из arr будет прочтено 4 байта, вместо необходимых мне 2-х
Такая же дурная ситуация получается и при обратной операции, когда мне нужно в arr записать 2 байта, но записывается 4.
Ну и естественно что тоже самое будет актуально и для 8 бит на отсчет. Без всяких проблем данные будут прочитаны только при 32 битах на отсчет.
И естественно нельзы сделать read(&f,2), потому что биты для кодирования вещественного числа размазаны по всему числу, а не идут по порядку.
Уфффф... Надеюсь понятно объяснил.