mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 16:57:23 -05:00
PulseAudio
Swap Pulse Audio in for all instance where OSS is used Lots of other potentially things breaking
This commit is contained in:
@@ -9,25 +9,32 @@ git_describe(GIT_TAG)
|
||||
find_package(LibSndFile REQUIRED)
|
||||
find_package(MBE REQUIRED)
|
||||
find_package(ITPP REQUIRED)
|
||||
find_package(LibPortAudio) #disabled for testing
|
||||
#find_package(LibPortAudio) #disabled for testing
|
||||
find_package(RTLSDR)
|
||||
#more messing around
|
||||
#find_package(Curses REQUIRED)
|
||||
find_package(PULSEAUDIO)
|
||||
|
||||
#include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${ITPP_INCLUDE_DIR} ${CURSES_INCLUDE_DIR})
|
||||
#set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${ITPP_LIBRARY} ${CURSES_LIBRARY})
|
||||
|
||||
include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${ITPP_INCLUDE_DIR} ${CURSES_INCLUDE_DIR})
|
||||
set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${ITPP_LIBRARY})
|
||||
include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${ITPP_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIRS} )
|
||||
set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${ITPP_LIBRARY} ${PULSEAUDIO_SIMPLE_LIBRARY})
|
||||
|
||||
#going to disable PortAudio, works just fine with padsp in Linux,
|
||||
#hoping disabling this doesn't break OSX or cygwin, etc builds
|
||||
|
||||
if(PORTAUDIO_FOUND)
|
||||
include_directories(SYSTEM ${PORTAUDIO_INCLUDE_DIRS})
|
||||
list(APPEND LIBS ${PORTAUDIO_LIBRARIES})
|
||||
add_definitions(-DUSE_PORTAUDIO)
|
||||
endif(PORTAUDIO_FOUND)
|
||||
#if(PORTAUDIO_FOUND)
|
||||
# include_directories(SYSTEM ${PORTAUDIO_INCLUDE_DIRS})
|
||||
# list(APPEND LIBS ${PORTAUDIO_LIBRARIES})
|
||||
# add_definitions(-DUSE_PORTAUDIO)
|
||||
#endif(PORTAUDIO_FOUND)
|
||||
|
||||
#if(PULSEAUDIO_FOUND) ##I don't think this will be necessary
|
||||
# include_directories(SYSTEM ${PULSEAUDIO_INCLUDE_DIRS})
|
||||
# list(APPEND LIBS ${PULSEAUDIO_LIBRARIES})
|
||||
# add_definitions(-DUSE_PULSEAUDIO)
|
||||
#endif(PULSEAUDIO_FOUND)
|
||||
|
||||
if(RTLSDR_FOUND)
|
||||
find_package(Threads)
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
|
||||
#include "p25p1_heuristics.h"
|
||||
|
||||
#include <pulse/simple.h> //PULSE AUDIO
|
||||
#include <pulse/error.h> //PULSE AUDIO
|
||||
|
||||
#define SAMPLE_RATE_IN 48000 //48000
|
||||
#define SAMPLE_RATE_OUT 8000 //8000,
|
||||
@@ -144,6 +146,15 @@ typedef struct
|
||||
int rtl_udp_port;
|
||||
int rtl_bandwidth;
|
||||
int monitor_input_audio;
|
||||
int pulse_raw_rate_in;
|
||||
int pulse_raw_rate_out;
|
||||
int pulse_digi_rate_in;
|
||||
int pulse_digi_rate_out;
|
||||
pa_simple *pulse_raw_dev_in;
|
||||
pa_simple *pulse_raw_dev_out;
|
||||
pa_simple *pulse_digi_dev_in;
|
||||
pa_simple *pulse_digi_dev_out;
|
||||
|
||||
} dsd_opts;
|
||||
|
||||
typedef struct
|
||||
@@ -296,8 +307,10 @@ typedef struct
|
||||
void processDMRdata (dsd_opts * opts, dsd_state * state);
|
||||
void processDMRvoice (dsd_opts * opts, dsd_state * state);
|
||||
void processAudio (dsd_opts * opts, dsd_state * state);
|
||||
void playRawAudio (dsd_opts * opts, dsd_state * state); //added this one HERE HERE
|
||||
void playRawAudio (dsd_opts * opts, dsd_state * state); //added this one HERE HERE
|
||||
void processRawAudio (dsd_opts * opts, dsd_state * state); //added this one HERE HERE
|
||||
void openPulseInput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void openPulseOutput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void openAudioOutDevice (dsd_opts * opts, int speed);
|
||||
|
||||
369
include/dsd.h.bkp
Normal file
369
include/dsd.h.bkp
Normal file
@@ -0,0 +1,369 @@
|
||||
#ifndef DSD_H
|
||||
#define DSD_H
|
||||
/*
|
||||
* Copyright (C) 2010 DSD Author
|
||||
* GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#define __USE_XOPEN //compiler warning on this, needed for strptime, seems benign
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#ifdef SOLARIS
|
||||
#include <sys/audioio.h>
|
||||
#endif
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
#include <mbelib.h>
|
||||
#include <sndfile.h>
|
||||
|
||||
#include "p25p1_heuristics.h"
|
||||
|
||||
|
||||
#define SAMPLE_RATE_IN 48000 //48000
|
||||
#define SAMPLE_RATE_OUT 8000 //8000,
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
#include "portaudio.h"
|
||||
#define PA_FRAMES_PER_BUFFER 64
|
||||
//Buffer needs to be large enough to prevent input buffer overruns while DSD is doing other struff (like outputting voice)
|
||||
//else you get skipped samples which result in incomplete/erronous decodes and a mountain of error messages.
|
||||
#define PA_LATENCY_IN 0.500
|
||||
//Buffer needs to be large enough to prevent output buffer underruns while DSD is doing other stuff (like decoding input)
|
||||
//else you get choppy audio and in 'extreme' cases errors.
|
||||
//Buffer also needs to be as small as possible so we don't have a lot of audio delay.
|
||||
#define PA_LATENCY_OUT 0.100
|
||||
#endif
|
||||
|
||||
#ifdef USE_RTLSDR
|
||||
#include <rtl-sdr.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* global variables
|
||||
*/
|
||||
|
||||
static volatile int exitflag;
|
||||
//volatile int exitflag; //didn't work, couldn't build, multiple definitions of exitflag
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int onesymbol;
|
||||
char mbe_in_file[1024];
|
||||
FILE *mbe_in_f;
|
||||
int errorbars;
|
||||
int datascope;
|
||||
int symboltiming;
|
||||
int verbose;
|
||||
int p25enc;
|
||||
int p25lc;
|
||||
int p25status;
|
||||
int p25tg;
|
||||
int scoperate;
|
||||
char audio_in_dev[1024];
|
||||
int audio_in_fd;
|
||||
SNDFILE *audio_in_file;
|
||||
SF_INFO *audio_in_file_info;
|
||||
#ifdef USE_PORTAUDIO
|
||||
PaStream* audio_in_pa_stream;
|
||||
#endif
|
||||
uint32_t rtlsdr_center_freq;
|
||||
int rtlsdr_ppm_error;
|
||||
int audio_in_type; // 0 for device, 1 for file, 2 for portaudio, 3 for rtlsdr
|
||||
char audio_out_dev[1024];
|
||||
int audio_out_fd;
|
||||
SNDFILE *audio_out_file;
|
||||
SF_INFO *audio_out_file_info;
|
||||
#ifdef USE_PORTAUDIO
|
||||
PaStream* audio_out_pa_stream;
|
||||
#endif
|
||||
int audio_out_type; // 0 for device, 1 for file, 2 for portaudio
|
||||
int split;
|
||||
int playoffset;
|
||||
char mbe_out_dir[1024];
|
||||
char mbe_out_file[1024];
|
||||
char mbe_out_path[1024];
|
||||
FILE *mbe_out_f;
|
||||
float audio_gain;
|
||||
int audio_out;
|
||||
char wav_out_file[1024];
|
||||
SNDFILE *wav_out_f;
|
||||
//int wav_out_fd;
|
||||
int serial_baud;
|
||||
char serial_dev[1024];
|
||||
int serial_fd;
|
||||
int resume;
|
||||
int frame_dstar;
|
||||
int frame_x2tdma;
|
||||
int frame_p25p1;
|
||||
int frame_nxdn48;
|
||||
int frame_nxdn96;
|
||||
int frame_dmr;
|
||||
int frame_provoice;
|
||||
int mod_c4fm;
|
||||
int mod_qpsk;
|
||||
int mod_gfsk;
|
||||
int uvquality;
|
||||
int inverted_x2tdma;
|
||||
int inverted_dmr;
|
||||
int mod_threshold;
|
||||
int ssize;
|
||||
int msize;
|
||||
int playfiles;
|
||||
int delay;
|
||||
int use_cosine_filter;
|
||||
int unmute_encrypted_p25;
|
||||
int rtl_dev_index;
|
||||
int rtl_gain_value;
|
||||
int rtl_squelch_level;
|
||||
int rtl_volume_multiplier;
|
||||
int rtl_udp_port;
|
||||
int rtl_bandwidth;
|
||||
int monitor_input_audio;
|
||||
} dsd_opts;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int *dibit_buf;
|
||||
int *dibit_buf_p;
|
||||
int repeat;
|
||||
short *audio_out_buf;
|
||||
short *audio_out_buf_p;
|
||||
float *audio_out_float_buf;
|
||||
float *audio_out_float_buf_p;
|
||||
float audio_out_temp_buf[160];
|
||||
float *audio_out_temp_buf_p;
|
||||
int audio_out_idx;
|
||||
int audio_out_idx2;
|
||||
//int wav_out_bytes;
|
||||
int center;
|
||||
int jitter;
|
||||
int synctype;
|
||||
int min;
|
||||
int max;
|
||||
int lmid;
|
||||
int umid;
|
||||
int minref;
|
||||
int maxref;
|
||||
int lastsample;
|
||||
int sbuf[128];
|
||||
int sidx;
|
||||
int maxbuf[1024];
|
||||
int minbuf[1024];
|
||||
int midx;
|
||||
char err_str[64];
|
||||
char fsubtype[16];
|
||||
char ftype[16];
|
||||
int symbolcnt;
|
||||
int rf_mod;
|
||||
int numflips;
|
||||
int lastsynctype;
|
||||
int lastp25type;
|
||||
int offset;
|
||||
int carrier;
|
||||
char tg[25][16];
|
||||
int tgcount;
|
||||
int lasttg;
|
||||
int lastsrc;
|
||||
int nac;
|
||||
int errs;
|
||||
int errs2;
|
||||
int mbe_file_type;
|
||||
int optind;
|
||||
int numtdulc;
|
||||
int firstframe;
|
||||
char slot0light[8];
|
||||
char slot1light[8];
|
||||
float aout_gain;
|
||||
float aout_max_buf[200];
|
||||
float *aout_max_buf_p;
|
||||
int aout_max_buf_idx;
|
||||
int samplesPerSymbol;
|
||||
int symbolCenter;
|
||||
char algid[9];
|
||||
char keyid[17];
|
||||
int currentslot;
|
||||
mbe_parms *cur_mp;
|
||||
mbe_parms *prev_mp;
|
||||
mbe_parms *prev_mp_enhanced;
|
||||
int p25kid;
|
||||
|
||||
unsigned int debug_audio_errors;
|
||||
unsigned int debug_header_errors;
|
||||
unsigned int debug_header_critical_errors;
|
||||
|
||||
// Last dibit read
|
||||
int last_dibit;
|
||||
|
||||
// Heuristics state data for +P5 signals
|
||||
P25Heuristics p25_heuristics;
|
||||
|
||||
// Heuristics state data for -P5 signals
|
||||
P25Heuristics inv_p25_heuristics;
|
||||
|
||||
//input sample buffer for monitoring Input
|
||||
short input_sample_buffer; //HERE HERE
|
||||
//float *input_sample_buffer; //HERE HERE
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
char debug_prefix;
|
||||
char debug_prefix_2;
|
||||
unsigned int debug_sample_index;
|
||||
unsigned int debug_sample_left_edge;
|
||||
unsigned int debug_sample_right_edge;
|
||||
FILE* debug_label_file;
|
||||
FILE* debug_label_dibit_file;
|
||||
FILE* debug_label_imbe_file;
|
||||
#endif
|
||||
|
||||
} dsd_state;
|
||||
|
||||
/*
|
||||
* Frame sync patterns
|
||||
*/
|
||||
#define INV_P25P1_SYNC "333331331133111131311111"
|
||||
#define P25P1_SYNC "111113113311333313133333"
|
||||
|
||||
#define X2TDMA_BS_VOICE_SYNC "113131333331313331113311"
|
||||
#define X2TDMA_BS_DATA_SYNC "331313111113131113331133"
|
||||
#define X2TDMA_MS_DATA_SYNC "313113333111111133333313"
|
||||
#define X2TDMA_MS_VOICE_SYNC "131331111333333311111131"
|
||||
|
||||
#define DSTAR_HD "131313131333133113131111"
|
||||
#define INV_DSTAR_HD "313131313111311331313333"
|
||||
#define DSTAR_SYNC "313131313133131113313111"
|
||||
#define INV_DSTAR_SYNC "131313131311313331131333"
|
||||
// original sync numbers which is FSW plus LICH
|
||||
#define NXDN_MS_DATA_SYNC "313133113131111333"
|
||||
#define INV_NXDN_MS_DATA_SYNC "131311331313333111"
|
||||
#define NXDN_MS_VOICE_SYNC "313133113131113133"
|
||||
#define INV_NXDN_MS_VOICE_SYNC "131311331313331311"
|
||||
#define INV_NXDN_BS_DATA_SYNC "131311331313333131"
|
||||
#define NXDN_BS_DATA_SYNC "313133113131111313"
|
||||
#define INV_NXDN_BS_VOICE_SYNC "131311331313331331"
|
||||
#define NXDN_BS_VOICE_SYNC "313133113131113113"
|
||||
|
||||
//Try using only FSW and no LICH
|
||||
/*
|
||||
#define NXDN_MS_DATA_SYNC "3131331131"
|
||||
#define INV_NXDN_MS_DATA_SYNC "1313113313"
|
||||
#define NXDN_MS_VOICE_SYNC "313133113131113133"
|
||||
#define INV_NXDN_MS_VOICE_SYNC "131311331313331311"
|
||||
#define INV_NXDN_BS_DATA_SYNC "1313113313"
|
||||
#define NXDN_BS_DATA_SYNC "3131331131"
|
||||
#define INV_NXDN_BS_VOICE_SYNC "131311331313331331"
|
||||
#define NXDN_BS_VOICE_SYNC "313133113131113113"
|
||||
//how do two values equate to 4 symbol types? shouldn't it be -3, -1, 1, 3?
|
||||
*/
|
||||
|
||||
#define DMR_BS_DATA_SYNC "313333111331131131331131"
|
||||
#define DMR_BS_VOICE_SYNC "131111333113313313113313"
|
||||
#define DMR_MS_DATA_SYNC "311131133313133331131113"
|
||||
#define DMR_MS_VOICE_SYNC "133313311131311113313331"
|
||||
|
||||
#define INV_PROVOICE_SYNC "31313111333133133311331133113311"
|
||||
#define PROVOICE_SYNC "13131333111311311133113311331133"
|
||||
#define INV_PROVOICE_EA_SYNC "13313133113113333311313133133311"
|
||||
#define PROVOICE_EA_SYNC "31131311331331111133131311311133"
|
||||
|
||||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
void processDMRdata (dsd_opts * opts, dsd_state * state);
|
||||
void processDMRvoice (dsd_opts * opts, dsd_state * state);
|
||||
void processAudio (dsd_opts * opts, dsd_state * state);
|
||||
void playRawAudio (dsd_opts * opts, dsd_state * state); //added this one HERE HERE
|
||||
void processRawAudio (dsd_opts * opts, dsd_state * state); //added this one HERE HERE
|
||||
void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void openAudioOutDevice (dsd_opts * opts, int speed);
|
||||
void openAudioInDevice (dsd_opts * opts);
|
||||
|
||||
int getDibit (dsd_opts * opts, dsd_state * state);
|
||||
int get_dibit_and_analog_signal (dsd_opts * opts, dsd_state * state, int * out_analog_signal);
|
||||
|
||||
void skipDibit (dsd_opts * opts, dsd_state * state, int count);
|
||||
void saveImbe4400Data (dsd_opts * opts, dsd_state * state, char *imbe_d);
|
||||
void saveAmbe2450Data (dsd_opts * opts, dsd_state * state, char *ambe_d);
|
||||
int readImbe4400Data (dsd_opts * opts, dsd_state * state, char *imbe_d);
|
||||
int readAmbe2450Data (dsd_opts * opts, dsd_state * state, char *ambe_d);
|
||||
void openMbeInFile (dsd_opts * opts, dsd_state * state);
|
||||
void closeMbeOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void openMbeOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void openWavOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void closeWavOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void printFrameInfo (dsd_opts * opts, dsd_state * state);
|
||||
void processFrame (dsd_opts * opts, dsd_state * state);
|
||||
void printFrameSync (dsd_opts * opts, dsd_state * state, char *frametype, int offset, char *modulation);
|
||||
int getFrameSync (dsd_opts * opts, dsd_state * state);
|
||||
int comp (const void *a, const void *b);
|
||||
void noCarrier (dsd_opts * opts, dsd_state * state);
|
||||
void initOpts (dsd_opts * opts);
|
||||
void initState (dsd_state * state);
|
||||
void usage ();
|
||||
void liveScanner (dsd_opts * opts, dsd_state * state);
|
||||
void cleanupAndExit (dsd_opts * opts, dsd_state * state);
|
||||
void sigfun (int sig);
|
||||
int main (int argc, char **argv);
|
||||
void playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv);
|
||||
void processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char ambe_fr[4][24], char imbe7100_fr[7][24]);
|
||||
void openSerial (dsd_opts * opts, dsd_state * state);
|
||||
void resumeScan (dsd_opts * opts, dsd_state * state);
|
||||
int getSymbol (dsd_opts * opts, dsd_state * state, int have_sync);
|
||||
void upsample (dsd_state * state, float invalue);
|
||||
void processDSTAR (dsd_opts * opts, dsd_state * state);
|
||||
void processNXDNVoice (dsd_opts * opts, dsd_state * state);
|
||||
void processNXDNData (dsd_opts * opts, dsd_state * state);
|
||||
void processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, char *lcinfo);
|
||||
void processHDU (dsd_opts * opts, dsd_state * state);
|
||||
void processLDU1 (dsd_opts * opts, dsd_state * state);
|
||||
void processLDU2 (dsd_opts * opts, dsd_state * state);
|
||||
void processTDU (dsd_opts * opts, dsd_state * state);
|
||||
void processTDULC (dsd_opts * opts, dsd_state * state);
|
||||
void processProVoice (dsd_opts * opts, dsd_state * state);
|
||||
void processX2TDMAdata (dsd_opts * opts, dsd_state * state);
|
||||
void processX2TDMAvoice (dsd_opts * opts, dsd_state * state);
|
||||
void processDSTAR_HD (dsd_opts * opts, dsd_state * state);
|
||||
short dmr_filter(short sample);
|
||||
short nxdn_filter(short sample);
|
||||
|
||||
//borrow from LEH for testing 'improved NXDN detection'
|
||||
int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr);
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void open_rtlsdr_stream(dsd_opts *opts);
|
||||
void cleanup_rtlsdr_stream();
|
||||
void get_rtlsdr_sample(int16_t *sample);
|
||||
void rtlsdr_sighandler();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // DSD_H
|
||||
143
src/dsd_audio.c
143
src/dsd_audio.c
@@ -17,67 +17,107 @@
|
||||
|
||||
#include "dsd.h"
|
||||
|
||||
pa_sample_spec ss;
|
||||
pa_sample_spec tt;
|
||||
pa_sample_spec zz;
|
||||
pa_sample_spec cc;
|
||||
|
||||
void openPulseOutput(dsd_opts * opts)
|
||||
{
|
||||
|
||||
ss.format = PA_SAMPLE_S16NE;
|
||||
ss.channels = 1;
|
||||
ss.rate = opts->pulse_raw_rate_out; //48000
|
||||
|
||||
tt.format = PA_SAMPLE_S16NE;
|
||||
tt.channels = 1;
|
||||
tt.rate = opts->pulse_digi_rate_out; //48000, switches to 8000 when using RTL dongle
|
||||
//printf("digi rate out = %d\n", opts->pulse_digi_rate_out);
|
||||
|
||||
//ss
|
||||
if (opts->monitor_input_audio == 1)
|
||||
{
|
||||
opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD FME", PA_STREAM_PLAYBACK, NULL, "Raw Audio Out", &ss, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
//tt
|
||||
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD FME", PA_STREAM_PLAYBACK, NULL, "Digi Audio Out", &tt, NULL, NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
void openPulseInput(dsd_opts * opts)
|
||||
{
|
||||
|
||||
zz.format = PA_SAMPLE_S16NE;
|
||||
zz.channels = 1;
|
||||
zz.rate = opts->pulse_raw_rate_in; //48000
|
||||
|
||||
cc.format = PA_SAMPLE_S16NE;
|
||||
cc.channels = 1;
|
||||
cc.rate = opts->pulse_digi_rate_in; //48000
|
||||
|
||||
//zz
|
||||
if (opts->monitor_input_audio == 1)
|
||||
{
|
||||
opts->pulse_raw_dev_in = pa_simple_new(NULL, "DSD FME", PA_STREAM_RECORD, NULL, "Raw Audio In", &zz, NULL, NULL, NULL);
|
||||
}
|
||||
//cc
|
||||
opts->pulse_digi_dev_in = pa_simple_new(NULL, "DSD FME", PA_STREAM_RECORD, NULL, "Digi Audio In", &cc, NULL, NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
void playRawAudio(dsd_opts * opts, dsd_state * state) {
|
||||
short obuf, outl, sample2, i, something;
|
||||
something = state->samplesPerSymbol / 5;
|
||||
/* //this method gets excellent results on gfsk provoice, but not at all on the others
|
||||
if (opts->audio_in_type == 0 && opts->frame_provoice == 1){ //hack, but might as well for this particular type since its nearly perfect
|
||||
read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2;
|
||||
}
|
||||
#ifdef USE_PORTAUDIO
|
||||
if (opts->audio_in_type == 2){
|
||||
Pa_ReadStream( opts->audio_in_pa_stream, &sample2, 1 ); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2;
|
||||
}
|
||||
#endif
|
||||
if (opts->audio_in_type == 3){ //can't seem to grab get_rtlsdr_sample here, can't share it with dsd_symbol.c
|
||||
state->input_sample_buffer = state->lastsample;
|
||||
} //grabbing this one from dsd_symbol.c but its already been processed
|
||||
*/
|
||||
short obuf, outl, i, sample2, something;
|
||||
something = state->samplesPerSymbol / 1; //this was 5 in OSS, changed to 1 for pulse audio, no idea how it affects Port Audio
|
||||
|
||||
if (opts->audio_in_type == 0 && opts->audio_out_type == 0){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
//read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
pa_simple_read(opts->pulse_raw_dev_in, &sample2, 2, NULL );
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
write (opts->audio_out_fd, (void*)&obuf, 2);
|
||||
//write (opts->audio_out_fd, (void*)&obuf, 2);
|
||||
pa_simple_write(opts->pulse_raw_dev_out, (void*)&obuf, 2, NULL);
|
||||
}
|
||||
}
|
||||
#ifdef USE_PORTAUDIO
|
||||
if (opts->audio_in_type == 2 && opts->audio_out_type == 0){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
for (i=0; i < something * 5; i++){ //not sure if this should be 'something' or something * 5 like is was with OSS
|
||||
Pa_ReadStream( opts->audio_in_pa_stream, &sample2, 1 ); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
write (opts->audio_out_fd, (void*)&obuf, 2);
|
||||
//write (opts->audio_out_fd, (void*)&obuf, 2);
|
||||
pa_simple_write(opts->pulse_raw_dev_out, (void*)&obuf, 2, NULL);
|
||||
}
|
||||
}
|
||||
if (opts->audio_in_type == 0 && opts->audio_out_type == 2){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
//read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
pa_simple_read(opts->pulse_raw_dev_in, &sample2, 2, NULL );
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
Pa_StartStream( opts->audio_out_pa_stream ); //no promises this shit'll work
|
||||
Pa_WriteStream( opts->audio_out_pa_stream, (void*)&obuf, 2); //no promises this shit'll work
|
||||
Pa_StartStream( opts->audio_out_pa_stream ); //no promises this work
|
||||
Pa_WriteStream( opts->audio_out_pa_stream, (void*)&obuf, 2); //no promises this work
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->audio_in_type == 2 && opts->audio_out_type == 2){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
for (i=0; i < something * 5; i++){ //not sure if this should be 'something' or something * 5 like is was with OSS
|
||||
Pa_ReadStream( opts->audio_in_pa_stream, &sample2, 1 ); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
Pa_StartStream( opts->audio_out_pa_stream ); //no promises this shit'll work
|
||||
Pa_WriteStream( opts->audio_out_pa_stream, (void*)&obuf, 2); //no promises this shit'll work
|
||||
Pa_StartStream( opts->audio_out_pa_stream ); //no promises this work
|
||||
Pa_WriteStream( opts->audio_out_pa_stream, (void*)&obuf, 2); //no promises this work
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//shouldn't need to use ifdef rtl here since audio_in_type will never set to 3 unless its there in main
|
||||
if (opts->audio_in_type == 1 || opts->audio_in_type == 3){ //only plays at 83% and sounds like shit sadly, but can't get samples directly from sdr when its already being polled for samples
|
||||
|
||||
if (opts->audio_in_type == 1 || opts->audio_in_type == 3){ //only plays at 83% and sounds like s sadly, but can't get samples directly from sdr when its already being polled for samples
|
||||
//also, can't get samples from stdin more than once either it seems, unless I borked it when I tried it earlier, so lumping it in here as well
|
||||
for (i=0; i < something; i++)
|
||||
{
|
||||
obuf = state->input_sample_buffer; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
outl = sizeof(obuf) ; //obuf length, I think its always equal to 2
|
||||
if (opts->audio_out_type == 0){
|
||||
write (opts->audio_out_fd, (void*)&obuf, outl);}
|
||||
//write (opts->audio_out_fd, (void*)&obuf, outl);
|
||||
pa_simple_write(opts->pulse_raw_dev_out, (void*)&obuf, 2, NULL);
|
||||
}
|
||||
|
||||
#ifdef USE_PORTAUDIO //no idea if this method will work, since I can't test it
|
||||
if (opts->audio_out_type == 2){
|
||||
@@ -342,7 +382,6 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
if( err != paNoError )
|
||||
break;
|
||||
|
||||
//printf("write stream %d\n", state->audio_out_idx);
|
||||
err = Pa_WriteStream( opts->audio_out_pa_stream, (state->audio_out_buf_p - state->audio_out_idx), state->audio_out_idx );
|
||||
if( err != paNoError )
|
||||
break;
|
||||
@@ -357,9 +396,10 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2)); //12
|
||||
state->audio_out_idx = 0;
|
||||
else{
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idx = 0; }
|
||||
}
|
||||
|
||||
if (state->audio_out_idx2 >= 800000)
|
||||
@@ -450,6 +490,12 @@ void
|
||||
openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
{
|
||||
// get info of device/file
|
||||
/*
|
||||
if(strncmp(opts->audio_out_dev, "pulse", 5) == 0)
|
||||
{
|
||||
opts->audio_out_type == 0;
|
||||
}
|
||||
*/
|
||||
if(strncmp(opts->audio_out_dev, "pa:", 3) == 0)
|
||||
{
|
||||
opts->audio_out_type = 2;
|
||||
@@ -462,21 +508,26 @@ openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
if(strncmp(opts->audio_in_dev, "pulse", 5) == 0)
|
||||
{
|
||||
opts->audio_in_type = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stat stat_buf;
|
||||
if(stat(opts->audio_out_dev, &stat_buf) != 0)
|
||||
if(stat(opts->audio_out_dev, &stat_buf) != 0 && strncmp(opts->audio_out_dev, "pulse", 5 != 0)) //HERE
|
||||
{
|
||||
printf("Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( !(S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode)))
|
||||
if( (!(S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode))) && strncmp(opts->audio_out_dev, "pulse", 5 != 0))
|
||||
{
|
||||
// this is not a device
|
||||
printf("Error, %s is not a device. use -w filename for wav output.\n", opts->audio_out_dev);
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
#ifdef SOLARIS
|
||||
sample_info_t aset, aget;
|
||||
|
||||
@@ -484,7 +535,7 @@ openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
if (opts->audio_out_fd == -1)
|
||||
{
|
||||
printf ("Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
exit (1);
|
||||
//exit (1);
|
||||
}
|
||||
|
||||
// get current
|
||||
@@ -514,7 +565,7 @@ openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
{
|
||||
printf ("Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
opts->audio_out = 0;
|
||||
exit(1);
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
fmt = 0;
|
||||
@@ -539,6 +590,7 @@ openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
printf ("Audio Out Device: %s\n", opts->audio_out_dev);
|
||||
}
|
||||
@@ -559,7 +611,7 @@ openAudioInDevice (dsd_opts * opts)
|
||||
|
||||
if(opts->audio_in_file == NULL) {
|
||||
printf ("Error, couldn't open stdin with libsndfile: %s\n", sf_strerror(NULL));
|
||||
exit(1);
|
||||
//exit(1);
|
||||
}
|
||||
}
|
||||
else if(strncmp(opts->audio_in_dev, "pa:", 2) == 0)
|
||||
@@ -585,6 +637,10 @@ openAudioInDevice (dsd_opts * opts)
|
||||
else if(strncmp(opts->audio_in_dev, "rtl", 3) == 0)
|
||||
{
|
||||
opts->audio_in_type = 3;
|
||||
}
|
||||
else if(strncmp(opts->audio_in_dev, "pulse", 5) == 0)
|
||||
{
|
||||
opts->audio_in_type = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -610,8 +666,9 @@ openAudioInDevice (dsd_opts * opts)
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is a device, use old handling
|
||||
// this is a device, use old handling, pulse audio now
|
||||
opts->audio_in_type = 0;
|
||||
/*
|
||||
#ifdef SOLARIS
|
||||
sample_info_t aset, aget;
|
||||
int rgain;
|
||||
@@ -629,7 +686,7 @@ openAudioInDevice (dsd_opts * opts)
|
||||
if (opts->audio_in_fd == -1)
|
||||
{
|
||||
printf ("Error, couldn't open %s\n", opts->audio_in_dev);
|
||||
exit(1);
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
// get current
|
||||
@@ -652,7 +709,8 @@ openAudioInDevice (dsd_opts * opts)
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
*/
|
||||
/*
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
int fmt;
|
||||
|
||||
@@ -692,6 +750,7 @@ openAudioInDevice (dsd_opts * opts)
|
||||
printf ("ioctl setfmt error \n");
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
706
src/dsd_audio.c.bkp
Normal file
706
src/dsd_audio.c.bkp
Normal file
@@ -0,0 +1,706 @@
|
||||
/*
|
||||
* Copyright (C) 2010 DSD Author
|
||||
* GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dsd.h"
|
||||
|
||||
|
||||
void playRawAudio(dsd_opts * opts, dsd_state * state) {
|
||||
short obuf, outl, sample2, i, something;
|
||||
something = state->samplesPerSymbol / 5;
|
||||
/* //this method gets excellent results on gfsk provoice, but not at all on the others
|
||||
if (opts->audio_in_type == 0 && opts->frame_provoice == 1){ //hack, but might as well for this particular type since its nearly perfect
|
||||
read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2;
|
||||
}
|
||||
#ifdef USE_PORTAUDIO
|
||||
if (opts->audio_in_type == 2){
|
||||
Pa_ReadStream( opts->audio_in_pa_stream, &sample2, 1 ); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2;
|
||||
}
|
||||
#endif
|
||||
if (opts->audio_in_type == 3){ //can't seem to grab get_rtlsdr_sample here, can't share it with dsd_symbol.c
|
||||
state->input_sample_buffer = state->lastsample;
|
||||
} //grabbing this one from dsd_symbol.c but its already been processed
|
||||
*/
|
||||
if (opts->audio_in_type == 0 && opts->audio_out_type == 0){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
write (opts->audio_out_fd, (void*)&obuf, 2);
|
||||
}
|
||||
}
|
||||
#ifdef USE_PORTAUDIO
|
||||
if (opts->audio_in_type == 2 && opts->audio_out_type == 0){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
Pa_ReadStream( opts->audio_in_pa_stream, &sample2, 1 ); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
write (opts->audio_out_fd, (void*)&obuf, 2);
|
||||
}
|
||||
}
|
||||
if (opts->audio_in_type == 0 && opts->audio_out_type == 2){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
read (opts->audio_in_fd, &sample2, 2); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
Pa_StartStream( opts->audio_out_pa_stream ); //no promises this shit'll work
|
||||
Pa_WriteStream( opts->audio_out_pa_stream, (void*)&obuf, 2); //no promises this shit'll work
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->audio_in_type == 2 && opts->audio_out_type == 2){ //hack, but might as well for this particular type since its nearly perfect
|
||||
for (i=0; i < something; i++){
|
||||
Pa_ReadStream( opts->audio_in_pa_stream, &sample2, 1 ); //reading here seems to get same speed as gfsk modulation
|
||||
obuf = sample2 / 4; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
Pa_StartStream( opts->audio_out_pa_stream ); //no promises this shit'll work
|
||||
Pa_WriteStream( opts->audio_out_pa_stream, (void*)&obuf, 2); //no promises this shit'll work
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//shouldn't need to use ifdef rtl here since audio_in_type will never set to 3 unless its there in main
|
||||
if (opts->audio_in_type == 1 || opts->audio_in_type == 3){ //only plays at 83% and sounds like shit sadly, but can't get samples directly from sdr when its already being polled for samples
|
||||
//also, can't get samples from stdin more than once either it seems, unless I borked it when I tried it earlier, so lumping it in here as well
|
||||
for (i=0; i < something; i++)
|
||||
{
|
||||
obuf = state->input_sample_buffer; //dividing here 'quietens' it down a little bit, helps with clicking and clipping
|
||||
outl = sizeof(obuf) ; //obuf length, I think its always equal to 2
|
||||
if (opts->audio_out_type == 0){
|
||||
write (opts->audio_out_fd, (void*)&obuf, outl);}
|
||||
|
||||
#ifdef USE_PORTAUDIO //no idea if this method will work, since I can't test it
|
||||
if (opts->audio_out_type == 2){
|
||||
short err;
|
||||
err = Pa_IsStreamActive( opts->audio_out_pa_stream );
|
||||
if(err == 0)
|
||||
{
|
||||
err = Pa_StartStream( opts->audio_out_pa_stream );
|
||||
if( err != paNoError ){
|
||||
printf("Can't Start PA Stream");
|
||||
}
|
||||
err = Pa_WriteStream( opts->audio_out_pa_stream, (void*)&obuf, outl );
|
||||
if( err != paNoError ){
|
||||
printf("Can't Write PA Stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // end for loop
|
||||
} //end if statement
|
||||
|
||||
} //end playRawAudio
|
||||
|
||||
|
||||
void
|
||||
processAudio (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
int i, n;
|
||||
float aout_abs, max, gainfactor, gaindelta, maxbuf;
|
||||
|
||||
if (opts->audio_gain == (float) 0)
|
||||
{
|
||||
// detect max level
|
||||
max = 0;
|
||||
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
aout_abs = fabsf (*state->audio_out_temp_buf_p);
|
||||
if (aout_abs > max)
|
||||
{
|
||||
max = aout_abs;
|
||||
}
|
||||
state->audio_out_temp_buf_p++;
|
||||
}
|
||||
*state->aout_max_buf_p = max;
|
||||
state->aout_max_buf_p++;
|
||||
state->aout_max_buf_idx++;
|
||||
if (state->aout_max_buf_idx > 24)
|
||||
{
|
||||
state->aout_max_buf_idx = 0;
|
||||
state->aout_max_buf_p = state->aout_max_buf;
|
||||
}
|
||||
|
||||
// lookup max history
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
maxbuf = state->aout_max_buf[i];
|
||||
if (maxbuf > max)
|
||||
{
|
||||
max = maxbuf;
|
||||
}
|
||||
}
|
||||
|
||||
// determine optimal gain level
|
||||
if (max > (float) 0)
|
||||
{
|
||||
gainfactor = ((float) 30000 / max);
|
||||
}
|
||||
else
|
||||
{
|
||||
gainfactor = (float) 50;
|
||||
}
|
||||
if (gainfactor < state->aout_gain)
|
||||
{
|
||||
state->aout_gain = gainfactor;
|
||||
gaindelta = (float) 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gainfactor > (float) 50)
|
||||
{
|
||||
gainfactor = (float) 50;
|
||||
}
|
||||
gaindelta = gainfactor - state->aout_gain;
|
||||
if (gaindelta > ((float) 0.05 * state->aout_gain))
|
||||
{
|
||||
gaindelta = ((float) 0.05 * state->aout_gain);
|
||||
}
|
||||
}
|
||||
gaindelta /= (float) 160;
|
||||
}
|
||||
else
|
||||
{
|
||||
gaindelta = (float) 0;
|
||||
}
|
||||
|
||||
if(opts->audio_gain >= 0)
|
||||
{
|
||||
// adjust output gain
|
||||
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
*state->audio_out_temp_buf_p = (state->aout_gain + ((float) n * gaindelta)) * (*state->audio_out_temp_buf_p);
|
||||
state->audio_out_temp_buf_p++;
|
||||
}
|
||||
state->aout_gain += ((float) 160 * gaindelta);
|
||||
}
|
||||
|
||||
// copy audio data to output buffer and upsample if necessary
|
||||
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
||||
if (opts->split == 0)
|
||||
{
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
upsample (state, *state->audio_out_temp_buf_p);
|
||||
state->audio_out_temp_buf_p++;
|
||||
state->audio_out_float_buf_p += 6;
|
||||
state->audio_out_idx += 6;
|
||||
state->audio_out_idx2 += 6;
|
||||
}
|
||||
state->audio_out_float_buf_p -= (960 + opts->playoffset);
|
||||
// copy to output (short) buffer
|
||||
for (n = 0; n < 960; n++)
|
||||
{
|
||||
if (*state->audio_out_float_buf_p > 32767.0F)
|
||||
{
|
||||
*state->audio_out_float_buf_p = 32767.0F;
|
||||
}
|
||||
else if (*state->audio_out_float_buf_p < -32768.0F)
|
||||
{
|
||||
*state->audio_out_float_buf_p = -32768.0F;
|
||||
}
|
||||
*state->audio_out_buf_p = (short) *state->audio_out_float_buf_p;
|
||||
state->audio_out_buf_p++;
|
||||
state->audio_out_float_buf_p++;
|
||||
}
|
||||
state->audio_out_float_buf_p += opts->playoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
if (*state->audio_out_temp_buf_p > 32767.0F)
|
||||
{
|
||||
*state->audio_out_temp_buf_p = 32767.0F;
|
||||
}
|
||||
else if (*state->audio_out_temp_buf_p < -32768.0F)
|
||||
{
|
||||
*state->audio_out_temp_buf_p = -32768.0F;
|
||||
}
|
||||
*state->audio_out_buf_p = (short) *state->audio_out_temp_buf_p;
|
||||
state->audio_out_buf_p++;
|
||||
state->audio_out_temp_buf_p++;
|
||||
state->audio_out_idx++;
|
||||
state->audio_out_idx2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int n;
|
||||
short aout_buf[160];
|
||||
short *aout_buf_p;
|
||||
|
||||
// for(n=0; n<160; n++)
|
||||
// printf("%d ", ((short*)(state->audio_out_temp_buf))[n]);
|
||||
// printf("\n");
|
||||
|
||||
aout_buf_p = aout_buf;
|
||||
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
||||
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
if (*state->audio_out_temp_buf_p > (float) 32767)
|
||||
{
|
||||
*state->audio_out_temp_buf_p = (float) 32767;
|
||||
}
|
||||
else if (*state->audio_out_temp_buf_p < (float) -32768)
|
||||
{
|
||||
*state->audio_out_temp_buf_p = (float) -32768;
|
||||
}
|
||||
*aout_buf_p = (short) *state->audio_out_temp_buf_p;
|
||||
aout_buf_p++;
|
||||
state->audio_out_temp_buf_p++;
|
||||
}
|
||||
|
||||
sf_write_short(opts->wav_out_f, aout_buf, 160);
|
||||
/*
|
||||
|
||||
int n;
|
||||
short aout_buf[160];
|
||||
short *aout_buf_p;
|
||||
ssize_t result;
|
||||
|
||||
aout_buf_p = aout_buf;
|
||||
state->audio_out_temp_buf_p = state->audio_out_temp_buf;
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
if (*state->audio_out_temp_buf_p > (float) 32760)
|
||||
{
|
||||
*state->audio_out_temp_buf_p = (float) 32760;
|
||||
}
|
||||
else if (*state->audio_out_temp_buf_p < (float) -32760)
|
||||
{
|
||||
*state->audio_out_temp_buf_p = (float) -32760;
|
||||
}
|
||||
*aout_buf_p = (short) *state->audio_out_temp_buf_p;
|
||||
aout_buf_p++;
|
||||
state->audio_out_temp_buf_p++;
|
||||
}
|
||||
|
||||
result = write (opts->wav_out_fd, aout_buf, 320);
|
||||
fflush (opts->wav_out_f);
|
||||
state->wav_out_bytes += 320;
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
if (state->audio_out_idx > opts->delay)
|
||||
{
|
||||
// output synthesized speech to sound card
|
||||
if(opts->audio_out_type == 2)
|
||||
{
|
||||
#ifdef USE_PORTAUDIO
|
||||
PaError err = paNoError;
|
||||
do
|
||||
{
|
||||
long available = Pa_GetStreamWriteAvailable( opts->audio_out_pa_stream );
|
||||
if(available < 0)
|
||||
err = available;
|
||||
//printf("Frames available: %d\n", available);
|
||||
if( err != paNoError )
|
||||
break;
|
||||
if(available > SAMPLE_RATE_OUT * PA_LATENCY_OUT)
|
||||
{
|
||||
//It looks like this might not be needed for very small latencies. However, it's definitely needed for a bit larger ones.
|
||||
//When PA_LATENCY_OUT == 0.500 I get output buffer underruns if I don't use this. With PA_LATENCY_OUT <= 0.100 I don't see those happen.
|
||||
//But with PA_LATENCY_OUT < 0.100 I run the risk of choppy audio and stream errors.
|
||||
printf("\nSyncing voice output stream\n");
|
||||
err = Pa_StopStream( opts->audio_out_pa_stream );
|
||||
if( err != paNoError )
|
||||
break;
|
||||
}
|
||||
|
||||
err = Pa_IsStreamActive( opts->audio_out_pa_stream );
|
||||
if(err == 0)
|
||||
{
|
||||
printf("Start voice output stream\n");
|
||||
err = Pa_StartStream( opts->audio_out_pa_stream );
|
||||
}
|
||||
else if(err == 1)
|
||||
{
|
||||
err = paNoError;
|
||||
}
|
||||
if( err != paNoError )
|
||||
break;
|
||||
|
||||
//printf("write stream %d\n", state->audio_out_idx);
|
||||
err = Pa_WriteStream( opts->audio_out_pa_stream, (state->audio_out_buf_p - state->audio_out_idx), state->audio_out_idx );
|
||||
if( err != paNoError )
|
||||
break;
|
||||
} while(0);
|
||||
|
||||
if( err != paNoError )
|
||||
{
|
||||
fprintf( stderr, "An error occured while using the portaudio output stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2)); //12
|
||||
state->audio_out_idx = 0;
|
||||
}
|
||||
|
||||
if (state->audio_out_idx2 >= 800000)
|
||||
{
|
||||
state->audio_out_float_buf_p = state->audio_out_float_buf + 100;
|
||||
state->audio_out_buf_p = state->audio_out_buf + 100;
|
||||
memset (state->audio_out_float_buf, 0, 100 * sizeof (float));
|
||||
memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||
state->audio_out_idx2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
int getPADevice(char* dev, int input, PaStream** stream)
|
||||
{
|
||||
int devnum = atoi(dev + 3);
|
||||
printf("Using portaudio device %d.\n", devnum);
|
||||
|
||||
PaError err;
|
||||
|
||||
int numDevices = Pa_GetDeviceCount();
|
||||
if( numDevices < 0 )
|
||||
{
|
||||
printf( "ERROR: Pa_GetDeviceCount returned 0x%x\n", numDevices );
|
||||
err = numDevices;
|
||||
goto error;
|
||||
}
|
||||
if( devnum >= numDevices)
|
||||
{
|
||||
printf( "ERROR: Requested device %d is larger than number of devices.\n", devnum );
|
||||
return(1);
|
||||
}
|
||||
|
||||
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo( devnum );
|
||||
|
||||
/* print device name */
|
||||
#ifdef WIN32
|
||||
{ /* Use wide char on windows, so we can show UTF-8 encoded device names */
|
||||
wchar_t wideName[MAX_PATH];
|
||||
MultiByteToWideChar(CP_UTF8, 0, deviceInfo->name, -1, wideName, MAX_PATH-1);
|
||||
wprintf( L"Name = %s\n", wideName );
|
||||
}
|
||||
#else
|
||||
printf( "Name = %s\n", deviceInfo->name );
|
||||
#endif
|
||||
if((input == 1) && (deviceInfo->maxInputChannels == 0))
|
||||
{
|
||||
printf( "ERROR: Requested device %d is not an input device.\n", devnum );
|
||||
return(1);
|
||||
}
|
||||
if((input == 0) && (deviceInfo->maxOutputChannels == 0))
|
||||
{
|
||||
printf( "ERROR: Requested device %d is not an output device.\n", devnum );
|
||||
return(1);
|
||||
}
|
||||
|
||||
//Create stream parameters
|
||||
PaStreamParameters parameters;
|
||||
parameters.device = devnum;
|
||||
parameters.channelCount = 1; /* mono */
|
||||
parameters.sampleFormat = paInt16; //Shorts
|
||||
parameters.suggestedLatency = (input == 1) ? PA_LATENCY_IN : PA_LATENCY_OUT;
|
||||
parameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
//Open stream
|
||||
err = Pa_OpenStream(
|
||||
stream,
|
||||
(input == 1) ? ¶meters : NULL,
|
||||
(input == 0) ? ¶meters : NULL,
|
||||
(input == 1) ? SAMPLE_RATE_IN : SAMPLE_RATE_OUT,
|
||||
PA_FRAMES_PER_BUFFER,
|
||||
paClipOff,
|
||||
NULL /*callback*/,
|
||||
NULL );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fprintf( stderr, "An error occured while initializing a portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
{
|
||||
// get info of device/file
|
||||
if(strncmp(opts->audio_out_dev, "pa:", 3) == 0)
|
||||
{
|
||||
opts->audio_out_type = 2;
|
||||
#ifdef USE_PORTAUDIO
|
||||
int err = getPADevice(opts->audio_out_dev, 0, &opts->audio_out_pa_stream);
|
||||
if(err != 0)
|
||||
exit(err);
|
||||
#else
|
||||
printf("Error, Portaudio support not compiled.\n");
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stat stat_buf;
|
||||
if(stat(opts->audio_out_dev, &stat_buf) != 0)
|
||||
{
|
||||
printf("Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( !(S_ISCHR(stat_buf.st_mode) || S_ISBLK(stat_buf.st_mode)))
|
||||
{
|
||||
// this is not a device
|
||||
printf("Error, %s is not a device. use -w filename for wav output.\n", opts->audio_out_dev);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef SOLARIS
|
||||
sample_info_t aset, aget;
|
||||
|
||||
opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY);
|
||||
if (opts->audio_out_fd == -1)
|
||||
{
|
||||
printf ("Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
// get current
|
||||
ioctl (opts->audio_out_fd, AUDIO_GETINFO, &aset);
|
||||
aset.record.sample_rate = speed;
|
||||
aset.play.sample_rate = speed;
|
||||
aset.record.channels = 1;
|
||||
aset.play.channels = 1;
|
||||
aset.record.precision = 16;
|
||||
aset.play.precision = 16;
|
||||
aset.record.encoding = AUDIO_ENCODING_LINEAR;
|
||||
aset.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
|
||||
if (ioctl (opts->audio_out_fd, AUDIO_SETINFO, &aset) == -1)
|
||||
{
|
||||
printf ("Error setting sample device parameters\n");
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
|
||||
int fmt;
|
||||
|
||||
opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY);
|
||||
if (opts->audio_out_fd == -1)
|
||||
{
|
||||
printf ("Error, couldn't open %s\n", opts->audio_out_dev);
|
||||
opts->audio_out = 0;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_RESET) < 0)
|
||||
{
|
||||
printf ("ioctl reset error \n");
|
||||
}
|
||||
fmt = speed;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
|
||||
{
|
||||
printf ("ioctl speed error \n");
|
||||
}
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
|
||||
{
|
||||
printf ("ioctl stereo error \n");
|
||||
}
|
||||
fmt = AFMT_S16_LE;
|
||||
if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
||||
{
|
||||
printf ("ioctl setfmt error \n");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
printf ("Audio Out Device: %s\n", opts->audio_out_dev);
|
||||
}
|
||||
|
||||
void
|
||||
openAudioInDevice (dsd_opts * opts)
|
||||
{
|
||||
// get info of device/file
|
||||
if(strncmp(opts->audio_in_dev, "-", 1) == 0)
|
||||
{
|
||||
opts->audio_in_type = 1;
|
||||
opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
|
||||
opts->audio_in_file_info->samplerate=48000;
|
||||
opts->audio_in_file_info->channels=1;
|
||||
opts->audio_in_file_info->seekable=0;
|
||||
opts->audio_in_file_info->format=SF_FORMAT_RAW|SF_FORMAT_PCM_16|SF_ENDIAN_LITTLE;
|
||||
opts->audio_in_file = sf_open_fd(fileno(stdin), SFM_READ, opts->audio_in_file_info, 0);
|
||||
|
||||
if(opts->audio_in_file == NULL) {
|
||||
printf ("Error, couldn't open stdin with libsndfile: %s\n", sf_strerror(NULL));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if(strncmp(opts->audio_in_dev, "pa:", 2) == 0)
|
||||
{
|
||||
opts->audio_in_type = 2;
|
||||
#ifdef USE_PORTAUDIO
|
||||
int err = getPADevice(opts->audio_in_dev, 1, &opts->audio_in_pa_stream);
|
||||
if(err != 0)
|
||||
exit(err);
|
||||
|
||||
if (opts->split == 0)
|
||||
{
|
||||
int err = getPADevice(opts->audio_in_dev, 0, &opts->audio_out_pa_stream);
|
||||
if(err != 0)
|
||||
exit(err);
|
||||
}
|
||||
|
||||
#else
|
||||
printf("Error, Portaudio support not compiled.\n");
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
else if(strncmp(opts->audio_in_dev, "rtl", 3) == 0)
|
||||
{
|
||||
opts->audio_in_type = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stat stat_buf;
|
||||
if (stat(opts->audio_in_dev, &stat_buf) != 0)
|
||||
{
|
||||
printf("Error, couldn't open %s\n", opts->audio_in_dev);
|
||||
exit(1);
|
||||
}
|
||||
if (S_ISREG(stat_buf.st_mode))
|
||||
{
|
||||
// is this a regular file? then process with libsndfile.
|
||||
opts->audio_in_type = 1;
|
||||
opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
|
||||
opts->audio_in_file_info->channels = 1;
|
||||
opts->audio_in_file = sf_open(opts->audio_in_dev, SFM_READ, opts->audio_in_file_info);
|
||||
|
||||
if(opts->audio_in_file == NULL)
|
||||
{
|
||||
printf ("Error, couldn't open file %s\n", opts->audio_in_dev);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is a device, use old handling
|
||||
opts->audio_in_type = 0;
|
||||
#ifdef SOLARIS
|
||||
sample_info_t aset, aget;
|
||||
int rgain;
|
||||
|
||||
rgain = 64;
|
||||
|
||||
if (opts->split == 1)
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR);
|
||||
}
|
||||
if (opts->audio_in_fd == -1)
|
||||
{
|
||||
printf ("Error, couldn't open %s\n", opts->audio_in_dev);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// get current
|
||||
ioctl (opts->audio_in_fd, AUDIO_GETINFO, &aset);
|
||||
|
||||
aset.record.sample_rate = SAMPLE_RATE_IN;
|
||||
aset.play.sample_rate = SAMPLE_RATE_IN;
|
||||
aset.record.channels = 1;
|
||||
aset.play.channels = 1;
|
||||
aset.record.precision = 16;
|
||||
aset.play.precision = 16;
|
||||
aset.record.encoding = AUDIO_ENCODING_LINEAR;
|
||||
aset.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
aset.record.port = AUDIO_LINE_IN;
|
||||
aset.record.gain = rgain;
|
||||
|
||||
if (ioctl (opts->audio_in_fd, AUDIO_SETINFO, &aset) == -1)
|
||||
{
|
||||
printf ("Error setting sample device parameters\n");
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
int fmt;
|
||||
|
||||
if (opts->split == 1)
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR);
|
||||
}
|
||||
|
||||
if (opts->audio_in_fd == -1)
|
||||
{
|
||||
printf ("Error, couldn't open %s\n", opts->audio_in_dev);
|
||||
opts->audio_out = 0;
|
||||
}
|
||||
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_RESET) < 0)
|
||||
{
|
||||
printf ("ioctl reset error \n");
|
||||
}
|
||||
fmt = SAMPLE_RATE_IN;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SPEED, &fmt) < 0)
|
||||
{
|
||||
printf ("ioctl speed error \n");
|
||||
}
|
||||
fmt = 0;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_STEREO, &fmt) < 0)
|
||||
{
|
||||
printf ("ioctl stereo error \n");
|
||||
}
|
||||
fmt = AFMT_S16_LE;
|
||||
if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
||||
{
|
||||
printf ("ioctl setfmt error \n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->split == 1)
|
||||
{
|
||||
printf ("Audio In Device: %s\n", opts->audio_in_dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Audio In/Out Device: %s\n", opts->audio_in_dev);
|
||||
}
|
||||
}
|
||||
@@ -184,6 +184,11 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
while (sync == 0)
|
||||
{
|
||||
//printf("now=%d\n", now); //okay, so this is incrementing as expected
|
||||
if ( opts->monitor_input_audio == 1 && (time(NULL) - now) > 1 ) //okay, still something going on, still doing the read part for some reason
|
||||
{
|
||||
playRawAudio(opts, state); //this is on line 21 in dsd_audio.c
|
||||
}
|
||||
t++;
|
||||
symbol = getSymbol (opts, state, 0);
|
||||
|
||||
@@ -586,6 +591,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
else if ((strcmp (synctest32, INV_PROVOICE_SYNC) == 0) || (strcmp (synctest32, INV_PROVOICE_EA_SYNC) == 0))
|
||||
{
|
||||
now = time(NULL);
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
@@ -929,20 +935,12 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
printf ("Sync: no sync\n");
|
||||
printf("Press CTRL + C to close.\n"); //Kindly remind user to double tap CTRL + C
|
||||
}
|
||||
}
|
||||
noCarrier (opts, state);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (opts->monitor_input_audio == 1 && (time(NULL) - now) > 1 ) || (opts->monitor_input_audio == 1 && state->lastsynctype == -1) )
|
||||
{
|
||||
//printf ("Playing Raw Audio - Should Keep Printing Over and over\n");
|
||||
playRawAudio(opts, state); //this is on line 21 in dsd_audio.c
|
||||
//currently working on playRawAudio and samples grabbed in dsd_symbol, going to do it outside of the other big loop
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (-1);
|
||||
|
||||
@@ -136,12 +136,14 @@ initOpts (dsd_opts * opts)
|
||||
opts->p25status = 0;
|
||||
opts->p25tg = 0;
|
||||
opts->scoperate = 15;
|
||||
sprintf (opts->audio_in_dev, "/dev/audio");
|
||||
//sprintf (opts->audio_in_dev, "/dev/audio");
|
||||
sprintf (opts->audio_in_dev, "pulse");
|
||||
opts->audio_in_fd = -1;
|
||||
#ifdef USE_PORTAUDIO
|
||||
opts->audio_in_pa_stream = NULL;
|
||||
#endif
|
||||
sprintf (opts->audio_out_dev, "/dev/audio");
|
||||
//sprintf (opts->audio_out_dev, "/dev/audio");
|
||||
sprintf (opts->audio_out_dev, "pulse");
|
||||
opts->audio_out_fd = -1;
|
||||
#ifdef USE_PORTAUDIO
|
||||
opts->audio_out_pa_stream = NULL;
|
||||
@@ -186,6 +188,10 @@ initOpts (dsd_opts * opts)
|
||||
opts->rtl_volume_multiplier = 1; //set multipler from rtl sample to 'boost volume'
|
||||
opts->rtl_udp_port = 6020; //set UDP port for RTL remote
|
||||
opts->rtl_bandwidth = 48; //48000 default value
|
||||
opts->pulse_raw_rate_in = 48000;
|
||||
opts->pulse_raw_rate_out = 48000;
|
||||
opts->pulse_digi_rate_in = 48000;
|
||||
opts->pulse_digi_rate_out = 48000; //need to copy this to rtl type in and change rate out to 8000
|
||||
}
|
||||
|
||||
void
|
||||
@@ -312,8 +318,10 @@ usage ()
|
||||
printf (" -z <num> Frame rate for datascope\n");
|
||||
printf ("\n");
|
||||
printf ("Input/Output options:\n");
|
||||
printf (" -i <device> Audio input device (default is /dev/audio, - for piped stdin, rtl for rtl device)\n");
|
||||
printf (" -o <device> Audio output device (default is /dev/audio)\n");
|
||||
//printf (" -i <device> Audio input device (default is /dev/audio, - for piped stdin, rtl for rtl device)\n");
|
||||
printf (" -i <device> Audio input device (default is pulse audio, - for piped stdin, rtl for rtl device)\n");
|
||||
//printf (" -o <device> Audio output device (default is /dev/audio)\n");
|
||||
printf (" -o <device> Audio output device (default is pulse audio)\n");
|
||||
printf (" -d <dir> Create mbe data files, use this directory\n");
|
||||
printf (" -r <files> Read/Play saved mbe data from file(s)\n");
|
||||
printf (" -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
|
||||
@@ -372,6 +380,7 @@ usage ()
|
||||
void
|
||||
liveScanner (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
//move open pulse below rtl type to set up audio rate out hopefully
|
||||
#ifdef USE_PORTAUDIO
|
||||
if(opts->audio_in_type == 2)
|
||||
{
|
||||
@@ -388,9 +397,18 @@ liveScanner (dsd_opts * opts, dsd_state * state)
|
||||
#ifdef USE_RTLSDR
|
||||
if(opts->audio_in_type == 3)
|
||||
{
|
||||
opts->pulse_digi_rate_out = 8000; //rtl currently needs rate out to be 8000, will investigate this further
|
||||
open_rtlsdr_stream(opts);
|
||||
}
|
||||
#endif
|
||||
if (opts->audio_in_type == 0){
|
||||
openPulseInput(opts);
|
||||
}
|
||||
if (opts->audio_out_type == 0){
|
||||
openPulseOutput(opts);
|
||||
}
|
||||
//openPulse(opts);
|
||||
|
||||
while (1)
|
||||
{
|
||||
noCarrier (opts, state);
|
||||
@@ -951,6 +969,15 @@ main (int argc, char **argv)
|
||||
openSerial (&opts, &state);
|
||||
}
|
||||
|
||||
if((strncmp(opts.audio_in_dev, "pulse", 5) == 0))
|
||||
{
|
||||
opts.audio_in_type == 0;
|
||||
}
|
||||
|
||||
if((strncmp(opts.audio_out_dev, "pulse", 5) == 0))
|
||||
{
|
||||
opts.audio_out_type == 0;
|
||||
}
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
if((strncmp(opts.audio_in_dev, "pa:", 3) == 0)
|
||||
@@ -996,6 +1023,7 @@ main (int argc, char **argv)
|
||||
openAudioOutDevice (&opts, SAMPLE_RATE_OUT);
|
||||
}
|
||||
openAudioInDevice (&opts);
|
||||
|
||||
/*
|
||||
setlocale(LC_ALL, "");
|
||||
sleep(3);
|
||||
@@ -1022,12 +1050,14 @@ main (int argc, char **argv)
|
||||
opts.split = 0;
|
||||
opts.playoffset = 25; // 38
|
||||
opts.delay = 0;
|
||||
openAudioInDevice (&opts);
|
||||
openAudioInDevice (&opts); //disabled all four instances of openAudio devices, in and out for now
|
||||
opts.audio_out_fd = opts.audio_in_fd;
|
||||
}
|
||||
|
||||
if (opts.playfiles == 1)
|
||||
{
|
||||
opts.pulse_digi_rate_out = 8000; //need set to 8000 for amb/imb playback
|
||||
openPulseOutput(&opts); //need to open it up for output
|
||||
playMbeFiles (&opts, &state, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,22 @@
|
||||
*/
|
||||
|
||||
#include "dsd.h"
|
||||
/*
|
||||
pa_simple *c;
|
||||
pa_sample_spec cc;
|
||||
|
||||
void openPulseDigi(dsd_opts * opts){
|
||||
|
||||
cc.format = PA_SAMPLE_S16NE;
|
||||
cc.channels = 1;
|
||||
//cc.rate = 48000; //for some reason, if INPUT is 8000, and output is 48000, sounds correct on NXDN48
|
||||
cc.rate = opts->pulse_digi_rate_in;
|
||||
|
||||
c = pa_simple_new(NULL, "DSD FME", PA_STREAM_RECORD, NULL, "Digi Audio In", &cc, NULL, NULL, NULL);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
@@ -81,10 +97,9 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
}
|
||||
|
||||
// Read the new sample from the input
|
||||
if(opts->audio_in_type == 0) {
|
||||
result = read (opts->audio_in_fd, &sample, 2);
|
||||
|
||||
|
||||
if(opts->audio_in_type == 0)
|
||||
{
|
||||
pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL );
|
||||
}
|
||||
else if (opts->audio_in_type == 1) {
|
||||
result = sf_read_short(opts->audio_in_file, &sample, 1);
|
||||
|
||||
Reference in New Issue
Block a user