felixzero / rpitx_alsa

An ALSA sound driver collecting sound samples for F5OEO's rpitx.
GNU General Public License v3.0
14 stars 2 forks source link

NFM mode (feature request) #3

Open azwirko opened 5 years ago

azwirko commented 5 years ago

Hi,

As I understand this module, it creates an Upper Sideband (USB) signal. Is it possible to create a mode switch and then take input audio on this device and create a Narrowband FM signal (NFM)? I'd like to use this module with Direwolf https://github.com/wb2osz/direwolf - That app can create AX.25 APRS packets on an RPi. AX.25 packet and APRS though is frequently used on the VHF & UHF bands requiring Frequency Modulation.

Thanks and 73!

andyz - K1RA

azwirko commented 5 years ago

Looking at the source it appears one would need to create a third PCM device in alsa_handling.c, that is something like:

/ Number 2 is mono only and takes (already pre-filtered) FM samples /

and make the following additions to alsa_handling.c

define MONO_FM_DEVICE_NAME "fmdata"

I assume you could use the existing buffer for mono audio data

static struct snd_pcm_hardware rpitx_pcm_mono_hw

but would need to add a new int and a new struct to

struct rpitx_device struct rpitx_private_data mono_fm_private_data; int is_mono_fm_open;

then add the following to

static int rpitx_pcm_close mydev->is_mono_fm_open = 0;

then add the following to

static int rpitx_probe mydev->is_mono_fm_open = 0;

mydev->mono_fm_private_data.is_stereo = 0;
mutex_init(&mydev->mono_fm_private_data.cable_lock);

/* Mono (FM data) playback device */
ret = snd_pcm_new(card, MONO_FM_DEVICE_NAME, 2, 1, 0, &mono_pcm);
if (ret < 0)
    goto __nodev;

and then add the following to

ssize_t rpitx_read_bytes_from_alsa_buffer

else if (mydev->is_mono_fm_open)
    ss = mydev->mono_fm_private_data.substream;

and change the Do the actual copy code to be like

} else if (mydev->is_mono_usb_open) {
    process_iq_period(buffer,
                      ss->runtime->dma_area + buffer_hw_pointer);
    buffer_hw_pointer += PERIOD_BYTES / 2;

} else if (mydev->is_mono_fm_open) {
    process_iq_period_fm(buffer,
                      ss->runtime->dma_area + buffer_hw_pointer);
    buffer_hw_pointer += PERIOD_BYTES / 2;

}

Finally it appears a new function would need to be created in iq_sample_generation.c

void process_iq_period_fm

that would create the I-Q FM samples for the mono input audio data buffer, but I have no idea what that code would be.

Am i on the right track? Can you confirm this is the right method to follow if I was to add and FM mode to your code?

73 & Thanks!

andyz - K1RA