Не по теме: позвольте мне начать с того, что Java для меня совершенно в новинку. Я занимаюсь программированием более 15 лет, и у меня никогда не было необходимости в этом, кроме модификации кодовой базы других, поэтому, пожалуйста, простите мое невежество и, возможно, неправильную терминологию. Я также не очень хорошо знаком с RF, поэтому, если я ухожу здесь, пожалуйста, дайте мне знать!
Я создаю радиопередатчик SDR (Software Defined Radio), и, хотя я могу успешно передавать на частоте, когда я отправляю поток (либо с микрофона устройства, либо байты из тон-генератор), то, что проходит через мой портативный приемник, звучит как статический.
Я считаю, что это связано с тем, что мой приемник настроен на прием NFM (узкополосная частотная модуляция) и WFM (широкополосная частотная модуляция), в то время как передача, исходящая из моего SDR, отправляет необработанные немодулированные данные.
Мой вопрос: как мне модулировать байты звука (т.е. InputStream), чтобы результирующие байты модулировались в FM (частотная модуляция) или AM (амплитудная модуляция ), что я могу передать через SDR?
Кажется, я не могу найти класс или пакет, который обрабатывает модуляцию (в конечном итоге мне придется модулировать WFM, FM, AM, SB, LSB, USB, DSB и т. Д.), Несмотря на то, что существует довольно много открытых исходных кодов Кодовые базы SDR, но если вы знаете, где я могу это найти, это в основном отвечает на этот вопрос. Все, что я нашел до сих пор, предназначалось для демодуляции.
Это класс, который я построил на основе ответа Xarph здесь, в StackOverflow, он просто возвращает массив байтов, содержащий простой немодулированный аудиосигнал, который затем можно использовать для воспроизведения звука через динамики (или передачи через SDR, но из-за того, что результат не модулируется должным образом, он не проходит должным образом на стороне приемника, что и вызывает у меня проблемы выяснение)
public class ToneGenerator {
public static byte[] generateTone() {
return generateTone(60, 1000, 8000);
}
public static byte[] generateTone(double duration) {
return generateTone(duration, 1000, 8000);
}
public static byte[] generateTone(double duration, double freqOfTone) {
return generateTone(duration, freqOfTone, 8000);
}
public static byte[] generateTone(double duration, double freqOfTone, int sampleRate) {
double dnumSamples = duration * sampleRate;
dnumSamples = Math.ceil(dnumSamples);
int numSamples = (int) dnumSamples;
double sample[] = new double[numSamples];
byte generatedSnd[] = new byte[2 * numSamples];
for (int i = 0; i < numSamples; ++i) { // Fill the sample array
sample[i] = Math.sin(freqOfTone * 2 * Math.PI * i / (sampleRate));
}
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalized.
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalised.
int idx = 0;
int i = 0 ;
int ramp = numSamples / 20 ; // Amplitude ramp as a percent of sample count
for (i = 0; i< ramp; ++i) { // Ramp amplitude up (to avoid clicks)
double dVal = sample[i];
// Ramp up to maximum
final short val = (short) ((dVal * 32767 * i/ramp));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
for (i = i; i< numSamples - ramp; ++i) { // Max amplitude for most of the samples
double dVal = sample[i];
// scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
for (i = i; i< numSamples; ++i) { // Ramp amplitude down
double dVal = sample[i];
// Ramp down to zero
final short val = (short) ((dVal * 32767 * (numSamples-i)/ramp ));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
return generatedSnd;
}
}
Ответом на это не обязательно должен быть код, на самом деле теория и понимание того, как работает модуляция FM или AM, когда дело доходит до обработки массива байтов и преобразования его в правильный формат, вероятно, будет более ценным, поскольку у меня будет для реализации большего количества режимов в будущем.