Network soundcard.

pull/1/head
hexameron 2015-05-25 15:11:09 +00:00
rodzic a3b3e49ccc
commit ae53109a87
11 zmienionych plików z 502 dodań i 56 usunięć

Wyświetl plik

@ -3922,25 +3922,43 @@ Fl_Tabs *tabsSoundCard=(Fl_Tabs *)0;
Fl_Group *tabAudio=(Fl_Group *)0;
Fl_Group *AudioOSS=(Fl_Group *)0;
Fl_Group *AudioTCP=(Fl_Group *)0;
static void cb_btnAudioIO(Fl_Round_Button*, void*) {
sound_update(SND_IDX_OSS);
sound_update(SND_IDX_TCP);
progdefaults.changed = true;
resetSoundCard();
}
Fl_Input_Choice *menuOSSDev=(Fl_Input_Choice *)0;
Fl_Input2 *inpIPServerHost=(Fl_Input2 *)0;
static void cb_menuOSSDev(Fl_Input_Choice* o, void*) {
scDevice[0] = scDevice[1] = progdefaults.OSSdevice = o->value();
resetSoundCard();
static void cb_inpIPServerHost(Fl_Input2* o, void*) {
scDevice[0] = progdefaults.IPServerHost = o->value();
progdefaults.changed = true;
resetSoundCard();
}
Fl_Input2 *inpIPServerPort=(Fl_Input2 *)0;
static void cb_inpIPServerPort(Fl_Input2* o, void*) {
scDevice[0] = progdefaults.IPServerPort = o->value();
progdefaults.changed = true;
resetSoundCard();
}
Fl_Group *AudioUDP=(Fl_Group *)0;
Fl_Round_Button *btnAudioIO[5]={(Fl_Round_Button *)0};
static void cb_btnAudioIO1(Fl_Round_Button*, void*) {
sound_update(SND_IDX_UDP);
progdefaults.changed = true;
resetSoundCard();
}
Fl_Group *AudioPort=(Fl_Group *)0;
static void cb_btnAudioIO1(Fl_Round_Button*, void*) {
static void cb_btnAudioIO2(Fl_Round_Button*, void*) {
sound_update(SND_IDX_PORT);
progdefaults.changed = true;
resetSoundCard();
@ -3966,7 +3984,7 @@ progdefaults.changed = true;
Fl_Group *AudioPulse=(Fl_Group *)0;
static void cb_btnAudioIO2(Fl_Round_Button*, void*) {
static void cb_btnAudioIO3(Fl_Round_Button*, void*) {
sound_update(SND_IDX_PULSE);
progdefaults.changed = true;
resetSoundCard();
@ -3982,9 +4000,7 @@ progdefaults.changed = true;
Fl_Group *AudioNull=(Fl_Group *)0;
Fl_Round_Button *btnAudioIO[4]={(Fl_Round_Button *)0};
static void cb_btnAudioIO3(Fl_Round_Button*, void*) {
static void cb_btnAudioIO4(Fl_Round_Button*, void*) {
sound_update(SND_IDX_NULL);
progdefaults.changed = true;
resetSoundCard();
@ -7949,7 +7965,7 @@ i on a\ntouch screen device such as a tablet."));
o->value(progdefaults.DOMINOEX_BW);
o->labelsize(FL_NORMAL_SIZE);
} // Fl_Counter2* valDominoEX_BW
{ Fl_Counter2* o = valDominoEX_ADJ = new Fl_Counter2(156, 166, 63, 20, _("Tone-spacing adjust"));
{ Fl_Counter2* o = valDominoEX_ADJ = new Fl_Counter2(206, 166, 63, 20, _("Tone-spacing adjust"));
valDominoEX_ADJ->tooltip(_("Tone-spacing adjust"));
valDominoEX_ADJ->type(1);
valDominoEX_ADJ->box(FL_UP_BOX);
@ -9637,28 +9653,63 @@ definition"));
{ tabsSoundCard = new Fl_Tabs(0, 25, 600, 355);
tabsSoundCard->selection_color(FL_LIGHT1);
{ tabAudio = new Fl_Group(0, 50, 600, 330, _("Devices"));
{ AudioOSS = new Fl_Group(55, 65, 490, 45);
AudioOSS->box(FL_ENGRAVED_FRAME);
{ btnAudioIO[0] = new Fl_Round_Button(65, 75, 53, 25, _("OSS"));
btnAudioIO[0]->tooltip(_("Use OSS audio server"));
{ AudioTCP = new Fl_Group(55, 65, 380, 45);
AudioTCP->box(FL_ENGRAVED_FRAME);
{ btnAudioIO[0] = new Fl_Round_Button(65, 75, 53, 25, _("TCP"));
btnAudioIO[0]->tooltip(_("Use TCP audio server"));
btnAudioIO[0]->down_box(FL_DOWN_BOX);
btnAudioIO[0]->selection_color((Fl_Color)1);
btnAudioIO[0]->callback((Fl_Callback*)cb_btnAudioIO);
} // Fl_Round_Button* btnAudioIO[0]
{ Fl_Input_Choice* o = menuOSSDev = new Fl_Input_Choice(424, 75, 110, 25, _("Device:"));
menuOSSDev->tooltip(_("Select device"));
menuOSSDev->callback((Fl_Callback*)cb_menuOSSDev);
o->value(progdefaults.OSSdevice.c_str());
} // Fl_Input_Choice* menuOSSDev
AudioOSS->end();
} // Fl_Group* AudioOSS
{ Fl_Input2* o = inpIPServerHost = new Fl_Input2(180, 75, 90, 25, _("Host:"));
inpIPServerHost->tooltip(_("TCP/UDP Server Host"));
inpIPServerHost->box(FL_DOWN_BOX);
inpIPServerHost->color(FL_BACKGROUND2_COLOR);
inpIPServerHost->selection_color(FL_SELECTION_COLOR);
inpIPServerHost->labeltype(FL_NORMAL_LABEL);
inpIPServerHost->labelfont(0);
inpIPServerHost->labelsize(14);
inpIPServerHost->labelcolor(FL_FOREGROUND_COLOR);
inpIPServerHost->callback((Fl_Callback*)cb_inpIPServerHost);
inpIPServerHost->align(Fl_Align(FL_ALIGN_LEFT));
inpIPServerHost->when(FL_WHEN_RELEASE);
o->value(progdefaults.IPServerHost.c_str());
inpIPServerHost->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpIPServerHost
{ Fl_Input2* o = inpIPServerPort = new Fl_Input2(320, 75, 90, 25, _("Port:"));
inpIPServerPort->tooltip(_("TCP/UDP Server Port"));
inpIPServerPort->box(FL_DOWN_BOX);
inpIPServerPort->color(FL_BACKGROUND2_COLOR);
inpIPServerPort->selection_color(FL_SELECTION_COLOR);
inpIPServerPort->labeltype(FL_NORMAL_LABEL);
inpIPServerPort->labelfont(0);
inpIPServerPort->labelsize(14);
inpIPServerPort->labelcolor(FL_FOREGROUND_COLOR);
inpIPServerPort->callback((Fl_Callback*)cb_inpIPServerPort);
inpIPServerPort->align(Fl_Align(FL_ALIGN_LEFT));
inpIPServerPort->when(FL_WHEN_RELEASE);
o->value(progdefaults.IPServerPort.c_str());
inpIPServerPort->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpIPServerPort
AudioTCP->end();
} // Fl_Group* AudioTCP
{ AudioUDP = new Fl_Group(435, 65, 110, 45);
AudioUDP->box(FL_ENGRAVED_FRAME);
{ btnAudioIO[4] = new Fl_Round_Button(450, 75, 53, 25, _("UDP"));
btnAudioIO[4]->tooltip(_("Use UDP audio server"));
btnAudioIO[4]->down_box(FL_DOWN_BOX);
btnAudioIO[4]->selection_color((Fl_Color)1);
btnAudioIO[4]->callback((Fl_Callback*)cb_btnAudioIO1);
} // Fl_Round_Button* btnAudioIO[4]
AudioUDP->end();
} // Fl_Group* AudioUDP
{ AudioPort = new Fl_Group(55, 110, 490, 80);
AudioPort->box(FL_ENGRAVED_FRAME);
{ btnAudioIO[1] = new Fl_Round_Button(65, 138, 95, 25, _("PortAudio"));
btnAudioIO[1]->tooltip(_("Use Port Audio server"));
btnAudioIO[1]->down_box(FL_DOWN_BOX);
btnAudioIO[1]->selection_color((Fl_Color)1);
btnAudioIO[1]->callback((Fl_Callback*)cb_btnAudioIO1);
btnAudioIO[1]->callback((Fl_Callback*)cb_btnAudioIO2);
} // Fl_Round_Button* btnAudioIO[1]
{ menuPortInDev = new Fl_Choice(244, 121, 290, 25, _("Capture:"));
menuPortInDev->tooltip(_("Audio input device"));
@ -9678,7 +9729,7 @@ definition"));
btnAudioIO[2]->tooltip(_("Use Pulse Audio server"));
btnAudioIO[2]->down_box(FL_DOWN_BOX);
btnAudioIO[2]->selection_color((Fl_Color)1);
btnAudioIO[2]->callback((Fl_Callback*)cb_btnAudioIO2);
btnAudioIO[2]->callback((Fl_Callback*)cb_btnAudioIO3);
} // Fl_Round_Button* btnAudioIO[2]
{ Fl_Input2* o = inpPulseServer = new Fl_Input2(310, 201, 225, 24, _("Server string:"));
inpPulseServer->tooltip(_("Leave this blank or refer to\nhttp://www.pulseaudio.org/wiki/ServerStrings"));
@ -9703,7 +9754,7 @@ definition"));
btnAudioIO[3]->tooltip(_("NO AUDIO DEVICE AVAILABLE (or testing)"));
btnAudioIO[3]->down_box(FL_DOWN_BOX);
btnAudioIO[3]->selection_color((Fl_Color)1);
btnAudioIO[3]->callback((Fl_Callback*)cb_btnAudioIO3);
btnAudioIO[3]->callback((Fl_Callback*)cb_btnAudioIO4);
} // Fl_Round_Button* btnAudioIO[3]
AudioNull->end();
} // Fl_Group* AudioNull

Wyświetl plik

@ -3343,7 +3343,7 @@ progdefaults.changed = true;}
callback {progdefaults.DOMINOEX_ADJ = o->value();
resetDOMEX();
progdefaults.changed = true;}
tooltip {Tone-spacing adjust} xywh {156 166 63 20} type Simple align 8 minimum -100 maximum 100 value 0
tooltip {Tone-spacing adjust} xywh {206 166 63 20} type Simple align 8 minimum -100 maximum 100 value 0
code0 {o->value(progdefaults.DOMINOEX_ADJ);}
code1 {o->labelsize(FL_NORMAL_SIZE);}
class Fl_Counter2
@ -4857,24 +4857,47 @@ when both in same macro definition} xywh {210 239 90 21} type Simple align 8 min
label Devices open
xywh {0 50 600 330}
} {
Fl_Group AudioOSS {open
xywh {55 65 490 45} box ENGRAVED_FRAME
Fl_Group AudioTCP {open
xywh {55 65 380 45} box ENGRAVED_FRAME
} {
Fl_Round_Button {btnAudioIO[0]} {
label OSS
callback {sound_update(SND_IDX_OSS);
label TCP
callback {sound_update(SND_IDX_TCP);
progdefaults.changed = true;
resetSoundCard();}
tooltip {Use OSS audio server} xywh {65 75 53 25} down_box DOWN_BOX selection_color 1
tooltip {Use TCP audio server} xywh {65 75 53 25} down_box DOWN_BOX selection_color 1
}
Fl_Input inpIPServerHost {
label {Host:}
callback {scDevice[0] = progdefaults.IPServerHost = o->value();
progdefaults.changed = true;
resetSoundCard();}
tooltip {TCP/UDP Server Host} xywh {180 75 90 25}
code0 {o->value(progdefaults.IPServerHost.c_str());}
code1 {inpIPServerHost->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
Fl_Input inpIPServerPort {
label {Port:}
callback {scDevice[0] = progdefaults.IPServerPort = o->value();
progdefaults.changed = true;
resetSoundCard();}
tooltip {TCP/UDP Server Port} xywh {320 75 90 25}
code0 {o->value(progdefaults.IPServerPort.c_str());}
code1 {inpIPServerPort->labelsize(FL_NORMAL_SIZE);}
class Fl_Input2
}
}
Fl_Group AudioUDP {open
xywh {435 65 110 45} box ENGRAVED_FRAME
} {
Fl_Round_Button {btnAudioIO[4]} {
label UDP
callback {sound_update(SND_IDX_UDP);
progdefaults.changed = true;
resetSoundCard();}
tooltip {Use UDP audio server} xywh {450 75 53 25} down_box DOWN_BOX selection_color 1
}
Fl_Input_Choice menuOSSDev {
label {Device:}
callback {scDevice[0] = scDevice[1] = progdefaults.OSSdevice = o->value();
resetSoundCard();
progdefaults.changed = true;} open
tooltip {Select device} xywh {424 75 110 25}
code0 {o->value(progdefaults.OSSdevice.c_str());}
} {}
}
Fl_Group AudioPort {open
xywh {55 110 490 80} box ENGRAVED_FRAME

Wyświetl plik

@ -460,16 +460,17 @@ extern Fl_Counter *mbw_delay;
extern Fl_Group *tabSoundCard;
extern Fl_Tabs *tabsSoundCard;
extern Fl_Group *tabAudio;
extern Fl_Group *AudioOSS;
#include <FL/Fl_Input_Choice.H>
extern Fl_Input_Choice *menuOSSDev;
extern Fl_Group *AudioTCP;
extern Fl_Input2 *inpIPServerHost;
extern Fl_Input2 *inpIPServerPort;
extern Fl_Group *AudioUDP;
extern Fl_Round_Button *btnAudioIO[5];
extern Fl_Group *AudioPort;
extern Fl_Choice *menuPortInDev;
extern Fl_Choice *menuPortOutDev;
extern Fl_Group *AudioPulse;
extern Fl_Input2 *inpPulseServer;
extern Fl_Group *AudioNull;
extern Fl_Round_Button *btnAudioIO[4];
extern Fl_Group *tabAudioOpt;
extern Fl_Group *grpAudioSampleRate;
extern Fl_ListBox *menuInSampleRate;
@ -591,6 +592,7 @@ extern Fl_Counter2 *cntTrackFreqMax;
#include <FL/Fl_Float_Input.H>
extern Fl_Float_Input *stationary_lat;
extern Fl_Float_Input *stationary_lon;
#include <FL/Fl_Input_Choice.H>
extern Fl_Input_Choice *inpGPSdev;
#include <FL/Fl_Spinner.H>
extern Fl_Output *gps_pos_lat;

Wyświetl plik

@ -462,16 +462,17 @@ extern Fl_Counter *mbw_delay;
extern Fl_Group *tabSoundCard;
extern Fl_Tabs *tabsSoundCard;
extern Fl_Group *tabAudio;
extern Fl_Group *AudioOSS;
extern Fl_Group *AudioIP;
extern Fl_Input2 *inpIPServerHost;
extern Fl_Input2 *inpIPServerPort;
#include <FL/Fl_Input_Choice.H>
extern Fl_Input_Choice *menuOSSDev;
extern Fl_Group *AudioPort;
extern Fl_Choice *menuPortInDev;
extern Fl_Choice *menuPortOutDev;
extern Fl_Group *AudioPulse;
extern Fl_Input2 *inpPulseServer;
extern Fl_Group *AudioNull;
extern Fl_Round_Button *btnAudioIO[4];
extern Fl_Round_Button *btnAudioIO[5];
extern Fl_Group *tabAudioOpt;
extern Fl_Group *grpAudioSampleRate;
extern Fl_ListBox *menuInSampleRate;

Wyświetl plik

@ -1019,11 +1019,17 @@
/* Sound card */ \
ELEM_(int, btnAudioIOis, "AUDIOIO", \
"Audio subsystem. Values are as follows:\n" \
" 0: OSS; 1: PortAudio; 2: PulseAudio; 3: File I/O", \
" 0: TCP; 1: PortAudio; 2: PulseAudio; 3: File I/O", \
SND_IDX_NULL) \
ELEM_(std::string, OSSdevice, "OSSDEVICE", \
"OSS device name", \
"") \
ELEM_(std::string, IPServerHost, "IPHOST", \
"IP stream host", \
"localhost") \
ELEM_(std::string, IPServerPort, "IPPORT", \
"IP stream port", \
"7355") \
ELEM_(std::string, PAdevice, "PADEVICE", \
"For compatibility with older versions", \
"") \

Wyświetl plik

@ -30,6 +30,7 @@
#include <string>
#include <cstring>
#include <climits>
#include <sys/socket.h>
#if USE_SNDFILE
# include <sndfile.h>
@ -349,4 +350,38 @@ public:
void flush(unsigned) { }
};
class SoundIP : public SoundBase
{
public:
SoundIP(const char* host="", const char* port="9999", bool udp_flag=false);
~SoundIP();
int Open(int mode, int freq = 8000);
void Close(unsigned);
void Abort(unsigned);
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(int dir = 0) { return false; }
void flush(unsigned) { }
private:
void readport();
int remote_connect(const char *, const char *, struct addrinfo);
int timeout_connect(int, const struct sockaddr *, socklen_t);
int getstream();
void closestream();
int readstream(uint8_t *buffer);
int portmode_udp;
int resamplerate;
int stream;
bool udp_connected;
const char *m_host, *m_port;
int buffptr, buffend;
uint8_t *cbuff;
float *snd_buffer;
float m_step;
};
#endif // SOUND_H

Wyświetl plik

@ -21,8 +21,8 @@
#ifndef SOUNDCONF_H
#define SOUNDCONF_H
enum { SND_IDX_UNKNOWN = -1, SND_IDX_OSS, SND_IDX_PORT,
SND_IDX_PULSE, SND_IDX_NULL, SND_IDX_END
enum { SND_IDX_UNKNOWN = -1, SND_IDX_TCP, SND_IDX_PORT,
SND_IDX_PULSE, SND_IDX_NULL, SND_IDX_UDP, SND_IDX_END
};
enum {

Wyświetl plik

@ -0,0 +1,188 @@
/* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Re-written nc(1) for OpenBSD. Original implementation by
* *Hobbit* <hobbit@avian.org>.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <poll.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
int SoundIP::getstream()
{
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = portmode_udp ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = portmode_udp ? IPPROTO_UDP : IPPROTO_TCP;
if (portmode_udp) {
hints.ai_flags = AI_PASSIVE;
udp_connected = false;
stream = remote_connect(NULL, m_port, hints);
} else
stream = remote_connect(m_host, m_port, hints);
return stream;
}
void SoundIP::closestream()
{
if (stream >= 0)
close(stream);
stream = -1;
}
/*
* remote_connect()
* Returns a socket connected to a remote host. Properly binds to a local
* port or source address if needed. Returns -1 on failure.
*/
int
SoundIP::remote_connect(const char *host, const char *port, struct addrinfo hints)
{
struct addrinfo *res, *res0;
int s, x, ret;
if ( getaddrinfo(host, port, &hints, &res) )
return -1;
res0 = res;
do {
if ((s = socket(res0->ai_family, res0->ai_socktype,
res0->ai_protocol)) < 0)
continue;
if (portmode_udp) {
x = 1;
ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
if (ret > -1)
if (bind(s, (struct sockaddr *)res0->ai_addr, res0->ai_addrlen) == 0)
break;
} else {
if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
break;
}
close(s);
s = -1;
} while ((res0 = res0->ai_next) != NULL);
freeaddrinfo(res);
return (s);
}
int
SoundIP::timeout_connect(int s, const struct sockaddr *name, socklen_t namelen)
{
struct pollfd pfd;
socklen_t optlen;
int ret, optval;
if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) {
pfd.fd = s;
pfd.events = POLLOUT;
if ((ret = poll(&pfd, 1, -1)) == 1) {
optlen = sizeof(optval);
if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR,
&optval, &optlen)) == 0) {
ret = optval == 0 ? 0 : -1;
}
} else
return -1;
}
return (ret);
}
/*
* readport()
* Loop that polls on the network file descriptor
*/
int
SoundIP::readstream(uint8_t *buffer)
{
struct pollfd pfd;
int n, plen, rv;
struct sockaddr_storage z;
socklen_t len = sizeof(z);
plen = 4096;
if (stream < 0)
return 0;
if (portmode_udp) {
rv = recvfrom(stream, buffer, plen, MSG_PEEK | MSG_DONTWAIT, (struct sockaddr *)&z, &len);
if (rv < 0)
return 0;
//rv = connect(stream, (struct sockaddr *)&z, len);
//udp_connected = true;
return ( read(stream, buffer, plen) );
}
/* Setup Network FD */
pfd.fd = stream;
pfd.events = POLLIN;
n = poll(&pfd, 1, -1);
if (n <= 0) {
closestream();
return n;
}
if (pfd.revents & POLLIN) {
n = read(stream, buffer, plen);
if (n == 0) {
closestream();
}
} else
n = 0;
return n;
}

Wyświetl plik

@ -2238,3 +2238,117 @@ size_t SoundNull::Read(float *buf, size_t count)
return count;
}
#include "netcat.c"
SoundIP::SoundIP(const char* inithost, const char* initport, bool udp_flag)
{
stream = -1;
m_host = inithost;
m_port = initport;
portmode_udp = udp_flag;
udp_connected = false;
snd_buffer = new float[SND_BUF_LEN]; // floats out for fldigi
cbuff = new uint8_t[SND_BUF_LEN]; // 64K, max tcp/ip packet size
buffend = buffptr = 0;
}
SoundIP::~SoundIP()
{
SoundIP::closestream();
delete [] snd_buffer;
delete [] cbuff;
}
int SoundIP::Open(int mode, int freq)
{
resamplerate = freq;
m_step = 0.0;
if (stream < 0)
SoundIP::getstream();
return 0;
}
void SoundIP::Close(unsigned unused)
{
SoundIP::closestream();
}
void SoundIP::Abort(unsigned unused)
{
SoundIP::closestream();
}
size_t SoundIP::Write(double* buf, size_t count)
{
return count;
}
size_t SoundIP::Write_stereo(double* bufleft, double* bufright, size_t count)
{
return count;
}
size_t SoundIP::Read(float *buff, size_t count)
{
int n, s, out, rate, idlecount;
unsigned i, j, c;
float ratio;
rate = progdefaults.in_sample_rate;
if (rate < 8000)
rate = 48000; // unset / native default
ratio = 1.0 * rate / resamplerate;
if (stream < 0) {
// keep trying to open stream
MilliSleep(1000);
SoundIP::getstream();
for (i = 0; i < count; i++)
buff[i] = 0.0f;
return count;
}
idlecount = 10;
out = 0;
c = count;
for (;;) {
i = buffend - buffptr;
if ( i > c )
i = c;
if ( i > 0) {
for ( j = 0; j < i; j++)
buff[out + j] = snd_buffer[buffptr + j];
}
buffptr += i;
out += i;
c -= i;
if ( 0 == c)
return count;
n = readstream(cbuff);
if (n <= 0) {
MilliSleep(100);
if (--idlecount < 0) {
for (i = 0; i < count; i++)
buff[i] = 0.0f;
return count;
}
}
buffend = buffptr = 0;
// S16LE to float, resampled
for (s = 0; s * 2 < n; s++) {
m_step = m_step - 1.0;
if (m_step < 0) {
short s16le = cbuff[2*s] | ( cbuff[2*s+1] << 8);
snd_buffer[buffend++] = (1.0 / 32768) * s16le;
m_step += ratio;
}
}
}
return count;
}

Wyświetl plik

@ -304,7 +304,7 @@ static void sound_init_options(void)
}
}
menuOSSDev->value(progdefaults.OSSdevice.c_str());
//menuOSSDev->value(progdefaults.OSSdevice.c_str());
inpPulseServer->value(progdefaults.PulseServer.c_str());
char sr[6+1];
@ -389,7 +389,7 @@ void sound_init(void)
init_portaudio();
// set the Sound Card configuration tab to the correct initial values
#if !USE_OSS
#if 0
AudioOSS->deactivate();
btnAudioIO[SND_IDX_OSS]->deactivate();
#endif
@ -403,7 +403,7 @@ void sound_init(void)
#endif
if (progdefaults.btnAudioIOis == SND_IDX_UNKNOWN ||
!btnAudioIO[progdefaults.btnAudioIOis]->active()) { // or saved sound api now disabled
int io[4] = { SND_IDX_PORT, SND_IDX_PULSE, SND_IDX_OSS, SND_IDX_NULL };
int io[5] = { SND_IDX_PORT, SND_IDX_PULSE, SND_IDX_NULL, SND_IDX_TCP, SND_IDX_UDP };
if (probe_pulseaudio()) { // prefer pulseaudio
io[0] = SND_IDX_PULSE;
io[1] = SND_IDX_PORT;
@ -419,7 +419,6 @@ void sound_init(void)
sound_init_options();
sound_update(progdefaults.btnAudioIOis);
}
void sound_close(void)
@ -436,10 +435,12 @@ void sound_update(unsigned idx)
btnAudioIO[i]->value(i == idx);
// devices
menuOSSDev->deactivate();
//menuOSSDev->deactivate();
menuPortInDev->deactivate();
menuPortOutDev->deactivate();
inpPulseServer->deactivate();
inpIPServerHost->deactivate();
inpIPServerPort->deactivate();
// settings
menuInSampleRate->deactivate();
@ -447,7 +448,18 @@ void sound_update(unsigned idx)
progdefaults.btnAudioIOis = idx;
switch (idx) {
#if USE_OSS
case SND_IDX_TCP:
inpIPServerHost->activate();
if (inpIPServerHost->value())
scDevice[0] = inpIPServerHost->value();
//no break;
case SND_IDX_UDP:
inpIPServerPort->activate();
if (inpIPServerPort->value())
scDevice[1] = inpIPServerPort->value();
menuInSampleRate->activate();
break;
#if 0
case SND_IDX_OSS:
menuOSSDev->activate();
scDevice[0] = scDevice[1] = menuOSSDev->value();

Wyświetl plik

@ -570,6 +570,13 @@ void trx_reset_loop()
}
switch (progdefaults.btnAudioIOis) {
case SND_IDX_UDP:
scard = new SoundIP(scDevice[0].c_str(), scDevice[1].c_str(), true);
break;
case SND_IDX_TCP:
scard = new SoundIP(scDevice[0].c_str(), scDevice[1].c_str(), false);
break;
#if USE_OSS
case SND_IDX_OSS:
scard = new SoundOSS(scDevice[0].c_str());
@ -618,6 +625,13 @@ void trx_start(void)
switch (progdefaults.btnAudioIOis) {
case SND_IDX_UDP:
scard = new SoundIP(scDevice[0].c_str(), scDevice[1].c_str(), true);
break;
case SND_IDX_TCP:
scard = new SoundIP(scDevice[0].c_str(), scDevice[1].c_str(), false);
break;
#if USE_OSS
case SND_IDX_OSS:
scard = new SoundOSS(scDevice[0].c_str());