Portaudio stream persistence mod

Changed stream behavior to open/close unless the stream
  is connected to a paJACK device.
    * corrected problem with h/w codecs that enable a PTT
      line whenever tx samples are present, including total
      silence.
    * eliminated audio transients when switching from transmit
      to receive
pull/2/head
David Freese 2010-02-22 09:24:55 -06:00 zatwierdzone przez Stelios Bounanos
rodzic 445c24a9f8
commit 9b80c2c93f
3 zmienionych plików z 40 dodań i 18 usunięć

Wyświetl plik

@ -100,7 +100,7 @@ public:
virtual size_t Write_stereo(double *, double *, size_t) = 0;
virtual size_t Read(float *, size_t) = 0;
virtual void flush(unsigned dir = UINT_MAX) = 0;
virtual bool must_close(void) = 0;
virtual bool must_close(int dir = 0) = 0;
#if USE_SNDFILE
void get_file_params(const char* def_fname, const char** fname, int* format);
int Capture(bool val);
@ -150,7 +150,7 @@ public:
size_t Write(double *, size_t);
size_t Write_stereo(double *, double *, size_t);
size_t Read(float *, size_t);
bool must_close(void) { return true; }
bool must_close(int dir = 0) { return true; }
void flush(unsigned dir = UINT_MAX) { wait_till_finished(); }
private:
@ -193,13 +193,14 @@ public:
size_t Write(double *buf, size_t count);
size_t Write_stereo(double *bufleft, double *bufright, size_t count);
size_t Read(float *buf, size_t count);
bool must_close(void);
bool must_close(int dir = 0);
void flush(unsigned dir = UINT_MAX);
private:
void src_data_reset(unsigned dir);
static long src_read_cb(void* arg, float** data);
size_t resample_write(float* buf, size_t count);
device_iterator name_to_device(const std::string& name);
void init_stream(unsigned dir);
void start_stream(unsigned dir);
void pause_stream(unsigned dir);
@ -276,7 +277,7 @@ public:
size_t Write(double* buf, size_t count);
size_t Write_stereo(double* bufleft, double* bufright, size_t count);
size_t Read(float *buf, size_t count);
bool must_close(void) { return false; }
bool must_close(int dir = 0) { return false; }
void flush(unsigned dir = UINT_MAX);
private:
@ -323,7 +324,7 @@ public:
size_t Write(double* buf, size_t count);
size_t Write_stereo(double* bufleft, double* bufright, size_t count);
size_t Read(float *buf, size_t count);
bool must_close(void) { return false; }
bool must_close(int dir = 0) { return false; }
void flush(unsigned) { }
};

Wyświetl plik

@ -860,7 +860,19 @@ int SoundPort::Open(int mode, int freq)
// do we need to (re)initialise the streams?
int ret = 0;
int sr[2] = { progdefaults.in_sample_rate, progdefaults.out_sample_rate };
for (size_t i = 0; i < 2; i++) {
// initialize stream if it is a JACK device, regardless of mode
device_iterator idev;
if (mode == O_WRONLY && (idev = name_to_device(sd[0].device)) != devs.end() &&
Pa_GetHostApiInfo((*idev)->hostApi)->type == paJACK)
mode = O_RDWR;
if (mode == O_RDONLY && (idev = name_to_device(sd[1].device)) != devs.end() &&
Pa_GetHostApiInfo((*idev)->hostApi)->type == paJACK)
mode = O_RDWR;
size_t start = (mode == O_RDONLY || mode == O_RDWR) ? 0 : 1,
end = (mode == O_WRONLY || mode == O_RDWR) ? 1 : 0;
for (size_t i = start; i <= end; i++) {
if ( !(stream_active(i) && (Pa_GetHostApiInfo((*sd[i].idev)->hostApi)->type == paJACK ||
old_sample_rate == freq ||
sr[i] != SAMPLE_RATE_AUTO)) ) {
@ -1243,6 +1255,15 @@ long SoundPort::src_read_cb(void* arg, float** data)
return vec[0].len / sd[0].params.channelCount;
}
SoundPort::device_iterator SoundPort::name_to_device(const string& name)
{
device_iterator i;
for (i = devs.begin(); i != devs.end(); ++i)
if (name == (*i)->name)
break;
return i;
}
void SoundPort::init_stream(unsigned dir)
{
const char* dir_str[2] = { "input", "output" };
@ -1250,12 +1271,8 @@ void SoundPort::init_stream(unsigned dir)
LOG_DEBUG("looking for device \"%s\"", sd[dir].device.c_str());
for (sd[dir].idev = devs.begin(); sd[dir].idev != devs.end(); ++sd[dir].idev) {
if (sd[dir].device == (*sd[dir].idev)->name) {
idx = sd[dir].idev - devs.begin(); // save this device index
break;
}
}
if ((sd[dir].idev = name_to_device(sd[dir].device)) != devs.end())
idx = sd[dir].idev - devs.begin();
if (idx == paNoDevice) { // no match
LOG_ERROR("Could not find device \"%s\", using default device", sd[dir].device.c_str());
PaDeviceIndex def = (dir == 0 ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice());
@ -1450,9 +1467,9 @@ bool SoundPort::full_duplex_device(const PaDeviceInfo* dev)
return dev->maxInputChannels > 0 && dev->maxOutputChannels > 0;
}
bool SoundPort::must_close(void)
bool SoundPort::must_close(int dir)
{
return false;
return Pa_GetHostApiInfo((*sd[dir].idev)->hostApi)->type != paJACK;
}
// Determine the sample rate that we will use. We try the modem's rate

Wyświetl plik

@ -170,6 +170,8 @@ void trx_trx_receive_loop()
active_modem->HistoryON(false);
}
}
if (scard->must_close(O_RDONLY))
scard->Close(O_RDONLY);
}
@ -218,8 +220,9 @@ void trx_trx_transmit_loop()
ReedSolomon->send(false);
scard->flush();
if (scard->must_close())
scard->Close();
if (scard->must_close(O_WRONLY))
scard->Close(O_WRONLY);
} else
MilliSleep(10);
@ -269,8 +272,9 @@ void trx_tune_loop()
return;
}
scard->flush();
if (scard->must_close())
scard->Close();
if (scard->must_close(O_WRONLY))
scard->Close(O_WRONLY);
_trx_tune = 0;
} else
MilliSleep(10);