diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2017-01-04 14:14:02 +0100 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2017-02-18 21:00:45 +0100 |
commit | 9ff8c3bb25422e100801f90c17b9c21118920cfd (patch) | |
tree | 5715f3cc08893ed86dfc2514c93797d12e24d461 /src/common/sender.c | |
parent | d54d3ac2654844c7b8e4ee67752941c9037d5f42 (diff) |
Rework on audio interface
Sound instance is now called audio instance and uses funcation pointers.
This gives a clean interface to be exchanged with other technologies,
linke SDR.
Diffstat (limited to 'src/common/sender.c')
-rw-r--r-- | src/common/sender.c | 123 |
1 files changed, 82 insertions, 41 deletions
diff --git a/src/common/sender.c b/src/common/sender.c index 3a5dc43..45760e1 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -32,13 +32,15 @@ static sender_t **sender_tailp = &sender_head; int cant_recover = 0; /* Init transceiver instance and link to list of transceivers. */ -int sender_create(sender_t *sender, int kanal, const char *sounddev, int samplerate, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback, double loss_volume, enum pilot_signal pilot_signal) +int sender_create(sender_t *sender, int kanal, double sendefrequenz, double empfangsfrequenz, const char *audiodev, int samplerate, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback, double loss_volume, enum pilot_signal pilot_signal) { - sender_t *master; + sender_t *master, *slave; int rc = 0; sender->kanal = kanal; - strncpy(sender->sounddev, sounddev, sizeof(sender->sounddev) - 1); + sender->sendefrequenz = sendefrequenz; + sender->empfangsfrequenz = empfangsfrequenz; + strncpy(sender->audiodev, audiodev, sizeof(sender->audiodev) - 1); sender->samplerate = samplerate; sender->rx_gain = rx_gain; sender->pre_emphasis = pre_emphasis; @@ -61,43 +63,36 @@ int sender_create(sender_t *sender, int kanal, const char *sounddev, int sampler rc = -EIO; goto error; } - if (!strcmp(master->sounddev, sounddev)) + if (!strcmp(master->audiodev, audiodev)) break; } if (master) { - // FIXME: link more than two channels - if (master->slave) { - PDEBUG(DSENDER, DEBUG_ERROR, "Sound device '%s' cannot be used for channel %d. It is already shared by channel %d and %d!\n", sounddev, kanal, master->kanal, master->slave->kanal); - rc = -EBUSY; - goto error; - } - if (!sound_is_stereo_capture(master->sound) || !sound_is_stereo_playback(master->sound)) { - PDEBUG(DSENDER, DEBUG_ERROR, "Sound device '%s' cannot be used for more than one channel, because one direction is mono!\n", sounddev); - rc = -EBUSY; - goto error; - } if (master->pilot_signal != PILOT_SIGNAL_NONE) { - PDEBUG(DSENDER, DEBUG_ERROR, "Cannot share sound device with channel %d, because second channel is used for pilot signal!\n", master->kanal); + PDEBUG(DSENDER, DEBUG_ERROR, "Cannot share audio device with channel %d, because second channel is used for pilot signal!\n", master->kanal); rc = -EBUSY; goto error; } if (pilot_signal != PILOT_SIGNAL_NONE) { - PDEBUG(DSENDER, DEBUG_ERROR, "Cannot share sound device with channel %d, because we need a stereo channel for pilot signal!\n", master->kanal); + PDEBUG(DSENDER, DEBUG_ERROR, "Cannot share audio device with channel %d, because we need a stereo channel for pilot signal!\n", master->kanal); rc = -EBUSY; goto error; } - /* link us to a master/slave */ - master->slave = sender; - // FIXME: link more than two channels, so link to last slave + /* link us to a master */ sender->master = master; + /* link master (or last slave) to us */ + for (slave = master; ; slave = slave->slave) { + if (!slave->slave) + break; + } + slave->slave = sender; } else { - /* open own device */ - sender->sound = sound_open(sounddev, samplerate); - if (!sender->sound) { - PDEBUG(DSENDER, DEBUG_ERROR, "No sound device!\n"); - - rc = -EIO; - goto error; + /* link audio device */ + { + sender->audio_open = sound_open; + sender->audio_close = sound_close; + sender->audio_read = sound_read; + sender->audio_write = sound_write; + sender->audio_get_inbuffer = sound_get_inbuffer; } } @@ -107,7 +102,7 @@ int sender_create(sender_t *sender, int kanal, const char *sounddev, int sampler goto error; } - rc = jitter_create(&sender->audio, samplerate / 5); + rc = jitter_create(&sender->dejitter, samplerate / 5); if (rc < 0) { PDEBUG(DSENDER, DEBUG_ERROR, "Failed to create and init audio buffer!\n"); goto error; @@ -151,6 +146,42 @@ error: return rc; } +int sender_open_audio(void) +{ + sender_t *master, *inst; + int channels; + int i; + + for (master = sender_head; master; master = master->next) { + /* skip audio slaves */ + if (master->master) + continue; + + /* get list of frequencies */ + channels = 0; + for (inst = master; inst; inst = inst->slave) { + channels++; + } + double tx_f[channels], rx_f[channels]; + for (i = 0, inst = master; inst; i++, inst = inst->slave) { + tx_f[i] = inst->sendefrequenz; + if (inst->loopback) + rx_f[i] = inst->sendefrequenz; + else + rx_f[i] = inst->empfangsfrequenz; + } + + /* open device */ + master->audio = master->audio_open(master->audiodev, tx_f, rx_f, channels, master->samplerate); + if (!master->audio) { + PDEBUG(DSENDER, DEBUG_ERROR, "No audio device!\n"); + return -EIO; + } + } + + return 0; +} + /* Destroy transceiver instance and unlink from list. */ void sender_destroy(sender_t *sender) { @@ -164,16 +195,16 @@ void sender_destroy(sender_t *sender) sender_tailp = &((*sender_tailp)->next); } - if (sender->sound) { - sound_close(sender->sound); - sender->sound = NULL; + if (sender->audio) { + sender->audio_close(sender->audio); + sender->audio = NULL; } wave_destroy_record(&sender->wave_rx_rec); wave_destroy_record(&sender->wave_tx_rec); wave_destroy_playback(&sender->wave_rx_play); - jitter_destroy(&sender->audio); + jitter_destroy(&sender->dejitter); } static void gen_pilotton(sender_t *sender, int16_t *samples, int length) @@ -221,19 +252,23 @@ void process_sender_audio(sender_t *sender, int *quit, int latspl) /* count instances for audio channel */ for (num_chan = 0, inst = sender; inst; num_chan++, inst = inst->slave); - if (sender->pilot_signal) { + if (sender->pilot_signal != PILOT_SIGNAL_NONE) { if (num_chan != 1) { PDEBUG(DSENDER, DEBUG_ERROR, "Software error, please fix!\n"); abort(); } - num_chan++; + num_chan = 2; } int16_t buff[num_chan][latspl], *samples[num_chan]; for (i = 0; i < num_chan; i++) samples[i] = buff[i]; - count = sound_get_inbuffer(sender->sound); + count = sender->audio_get_inbuffer(sender->audio); if (count < 0) { + /* special case when the device is not yet ready to transmit packets */ + if (count == -EAGAIN) { + goto transmit_later; + } PDEBUG(DSENDER, DEBUG_ERROR, "Failed to get samples in buffer (rc = %d)!\n", count); if (count == -EPIPE) { if (cant_recover) { @@ -252,7 +287,7 @@ cant_recover: for (i = 0, inst = sender; inst; i++, inst = inst->slave) { /* load TX data from audio loop or from sender instance */ if (inst->loopback == 3) - jitter_load(&inst->audio, samples[i], count); + jitter_load(&inst->dejitter, samples[i], count); else sender_send(inst, samples[i], count); if (inst->wave_tx_rec.fp) @@ -301,9 +336,9 @@ cant_recover: break; } - rc = sound_write(sender->sound, samples, count, num_chan); + rc = sender->audio_write(sender->audio, samples, count, num_chan); if (rc < 0) { - PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to sound device (rc = %d)\n", rc); + PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to audio device (rc = %d)\n", rc); if (rc == -EPIPE) { if (cant_recover) goto cant_recover; @@ -312,10 +347,16 @@ cant_recover: return; } } +transmit_later: - count = sound_read(sender->sound, samples, latspl, num_chan); + count = sender->audio_read(sender->audio, samples, latspl, num_chan); if (count < 0) { - PDEBUG(DSENDER, DEBUG_ERROR, "Failed to read from sound device (rc = %d)!\n", count); + /* special case when audio_read wants us to quit */ + if (count == -EPERM) { + *quit = 1; + return; + } + PDEBUG(DSENDER, DEBUG_ERROR, "Failed to read from audio device (rc = %d)!\n", count); if (count == -EPIPE) { if (cant_recover) goto cant_recover; @@ -341,7 +382,7 @@ cant_recover: sender_receive(inst, samples[i], count); } if (inst->loopback == 3) - jitter_save(&inst->audio, samples[i], count); + jitter_save(&inst->dejitter, samples[i], count); } } } |