- style cleanup

- remove multi_audio commented code
- don't connect in ctor, but in Node::Connected(), this way it doesn't hang up everything on startup even if it's not the selected system output.
- prepare for asynchronous connection
- add an enable checkbox and change parameter handling


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27010 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol
2008-08-17 18:37:23 +00:00
parent a4de1ff695
commit cbd43babfe
4 changed files with 167 additions and 173 deletions
@@ -46,6 +46,7 @@
#include <Debug.h> #include <Debug.h>
#include "ESDEndpoint.h" #include "ESDEndpoint.h"
ESDEndpoint::ESDEndpoint() ESDEndpoint::ESDEndpoint()
: BDataIO() : BDataIO()
, fHost(NULL) , fHost(NULL)
@@ -56,6 +57,7 @@ ESDEndpoint::ESDEndpoint()
Reset(); Reset();
} }
ESDEndpoint::~ESDEndpoint() ESDEndpoint::~ESDEndpoint()
{ {
CALLED(); CALLED();
@@ -64,8 +66,18 @@ ESDEndpoint::~ESDEndpoint()
fSocket = -1; fSocket = -1;
} }
void ESDEndpoint::Reset()
status_t
ESDEndpoint::InitCheck() const
{ {
return fInitStatus;
}
void
ESDEndpoint::Reset()
{
fInitStatus = B_NO_INIT;
fDefaultCommand = ESD_PROTO_STREAM_PLAY; fDefaultCommand = ESD_PROTO_STREAM_PLAY;
fDefaultCommandSent = false; fDefaultCommandSent = false;
fDefaultFormat = ESD_BITS8 | ESD_MONO; fDefaultFormat = ESD_BITS8 | ESD_MONO;
@@ -73,7 +85,9 @@ void ESDEndpoint::Reset()
fLatency = 0LL; fLatency = 0LL;
} }
status_t ESDEndpoint::SendAuthKey()
status_t
ESDEndpoint::SendAuthKey()
{ {
CALLED(); CALLED();
BPath kfPath; BPath kfPath;
@@ -106,13 +120,49 @@ status_t ESDEndpoint::SendAuthKey()
return write(fSocket, fAuthKey, ESD_MAX_KEY); return write(fSocket, fAuthKey, ESD_MAX_KEY);
} }
status_t ESDEndpoint::Connect(const char *host, uint16 port)
bool
ESDEndpoint::Connected() const
{ {
return (fInitStatus == B_OK);
}
status_t
ESDEndpoint::Connect(const char *host, uint16 port)
{
status_t err;
// set up connection asynchronously
fHost = host;
fPort = port;
err = fConnectThread = spawn_thread(_ConnectThread, "ESDEndpoint Connection", B_LOW_PRIORITY, this);
if (err < B_OK)
return err;
err = resume_thread(fConnectThread);
// TODO: return now instead and move Connect() call
wait_for_thread(fConnectThread, &err);
return err;
}
int32
ESDEndpoint::_ConnectThread(void *_arg)
{
ESDEndpoint *_this = (ESDEndpoint *)_arg;
return _this->ConnectThread();
}
int32
ESDEndpoint::ConnectThread(void)
{
const char *host = fHost.String();
uint16 port = fPort;
status_t err; status_t err;
int flag; int flag;
CALLED(); CALLED();
fHost = host;
fPort = port;
struct hostent *he; struct hostent *he;
struct sockaddr_in sin; struct sockaddr_in sin;
@@ -140,7 +190,7 @@ status_t ESDEndpoint::Connect(const char *host, uint16 port)
*/ */
err = connect(fSocket, (struct sockaddr *) &sin, sizeof(sin)); err = connect(fSocket, (struct sockaddr *) &sin, sizeof(sin));
PRINT(("connect: %s\n", strerror(err))); PRINT(("connect: %ld, %s\n", err, strerror(errno)));
if (err < 0) if (err < 0)
return errno; return errno;
@@ -220,17 +270,17 @@ status_t ESDEndpoint::Connect(const char *host, uint16 port)
setsockopt(fSocket, SOL_SOCKET, SO_SNDBUF, &flag, sizeof(flag)); setsockopt(fSocket, SOL_SOCKET, SO_SNDBUF, &flag, sizeof(flag));
*/ */
// read(fSocket, &ok, sizeof(uint32));
// connect
// auth // TODO: get default format
// ask server latency
// calc network latency (time (send+recv) / 2) ? fInitStatus = B_OK;
// get default format
return B_OK; return B_OK;
} }
status_t ESDEndpoint::Disconnect() status_t
ESDEndpoint::Disconnect()
{ {
CALLED(); CALLED();
if (fSocket > -1) if (fSocket > -1)
@@ -239,7 +289,8 @@ status_t ESDEndpoint::Disconnect()
return B_OK; return B_OK;
} }
status_t ESDEndpoint::SetCommand(esd_command_t cmd) status_t
ESDEndpoint::SetCommand(esd_command_t cmd)
{ {
CALLED(); CALLED();
if (fDefaultCommandSent) if (fDefaultCommandSent)
@@ -248,7 +299,8 @@ status_t ESDEndpoint::SetCommand(esd_command_t cmd)
return B_OK; return B_OK;
} }
status_t ESDEndpoint::SetFormat(int bits, int channels, float rate) status_t
ESDEndpoint::SetFormat(int bits, int channels, float rate)
{ {
esd_format_t fmt = 0; esd_format_t fmt = 0;
CALLED(); CALLED();
@@ -282,7 +334,8 @@ status_t ESDEndpoint::SetFormat(int bits, int channels, float rate)
return B_OK; return B_OK;
} }
status_t ESDEndpoint::GetServerInfo() status_t
ESDEndpoint::GetServerInfo()
{ {
CALLED(); CALLED();
struct serverinfo { struct serverinfo {
@@ -298,19 +351,22 @@ status_t ESDEndpoint::GetServerInfo()
return B_OK; return B_OK;
} }
bool ESDEndpoint::CanSend() bool
ESDEndpoint::CanSend()
{ {
CALLED(); CALLED();
return fDefaultCommandSent; return fDefaultCommandSent;
} }
ssize_t ESDEndpoint::Read(void *buffer, size_t size) ssize_t
ESDEndpoint::Read(void *buffer, size_t size)
{ {
CALLED(); CALLED();
return EINVAL; return EINVAL;
} }
ssize_t ESDEndpoint::Write(const void *buffer, size_t size) ssize_t
ESDEndpoint::Write(const void *buffer, size_t size)
{ {
status_t err = B_OK; status_t err = B_OK;
CALLED(); CALLED();
@@ -336,7 +392,8 @@ ssize_t ESDEndpoint::Write(const void *buffer, size_t size)
return err; return err;
} }
status_t ESDEndpoint::SendCommand(esd_command_t cmd, const uint8 *obuf, size_t olen, uint8 *ibuf, size_t ilen) status_t
ESDEndpoint::SendCommand(esd_command_t cmd, const uint8 *obuf, size_t olen, uint8 *ibuf, size_t ilen)
{ {
status_t err; status_t err;
CALLED(); CALLED();
@@ -358,7 +415,8 @@ status_t ESDEndpoint::SendCommand(esd_command_t cmd, const uint8 *obuf, size_t o
return err; return err;
} }
status_t ESDEndpoint::SendDefaultCommand() status_t
ESDEndpoint::SendDefaultCommand()
{ {
status_t err; status_t err;
struct { struct {
@@ -44,8 +44,11 @@ public:
~ESDEndpoint(); ~ESDEndpoint();
/* */ /* */
status_t InitCheck() const;
void Reset(); void Reset();
status_t SendAuthKey(); status_t SendAuthKey();
bool Connected() const;
status_t Connect(const char *host, uint16 port=ESD_DEFAULT_PORT); status_t Connect(const char *host, uint16 port=ESD_DEFAULT_PORT);
status_t Disconnect(); status_t Disconnect();
@@ -71,7 +74,12 @@ virtual ssize_t Write(const void *buffer, size_t size);
status_t SendCommand(esd_command_t cmd, const uint8 *obuf, size_t olen, uint8 *ibuf, size_t ilen); status_t SendCommand(esd_command_t cmd, const uint8 *obuf, size_t olen, uint8 *ibuf, size_t ilen);
status_t SendDefaultCommand(); status_t SendDefaultCommand();
private: private:
static int32 _ConnectThread(void *_arg);
int32 ConnectThread(void);
status_t fInitStatus;
thread_id fConnectThread;
BString fHost; BString fHost;
uint16 fPort; uint16 fPort;
int fSocket; int fSocket;
@@ -133,9 +133,11 @@ ESDSinkNode::ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config)
config->FindString("hostname", &fHostname); config->FindString("hostname", &fHostname);
} }
if (fHostname.Length() < 1) if (fHostname.Length() < 1)
fHostname = "192.168.0.253"; fHostname = "192.168.0.1";
fPort = ESD_DEFAULT_PORT;
fDevice = new ESDEndpoint(); fDevice = new ESDEndpoint();
/*
if (fDevice) { if (fDevice) {
if (fDevice->Connect(fHostname.String()) >= 0) { if (fDevice->Connect(fHostname.String()) >= 0) {
fDevice->SetCommand(); fDevice->SetCommand();
@@ -144,6 +146,10 @@ ESDSinkNode::ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config)
fInitCheckStatus = fDevice->SendDefaultCommand(); fInitCheckStatus = fDevice->SendDefaultCommand();
} }
} }
*/
if (!fDevice)
return;
fInitCheckStatus = B_OK;
} }
status_t ESDSinkNode::InitCheck(void) const status_t ESDSinkNode::InitCheck(void) const
@@ -432,6 +438,15 @@ status_t ESDSinkNode::Connected(
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
} }
//
if (fDevice) {
if (fDevice->Connect(fHostname.String(), fPort) >= 0) {
fDevice->SetCommand();
//fDevice->GetServerInfo();
fDevice->SetFormat(ESD_FMT, 2);
fInitCheckStatus = fDevice->SendDefaultCommand();
}
}
// use one buffer length latency // use one buffer length latency
fInternalLatency = with_format.u.raw_audio.buffer_size * 10000 / 2 fInternalLatency = with_format.u.raw_audio.buffer_size * 10000 / 2
/ ( (with_format.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK) / ( (with_format.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
@@ -1076,18 +1091,27 @@ ESDSinkNode::GetParameterValue(int32 id, bigtime_t* last_change, void* value, si
if (!fDevice) if (!fDevice)
return B_ERROR; return B_ERROR;
//PRINT(("id : %i\n", id)); //PRINT(("id : %i\n", id));
if (id == fWebHostId) { switch (id) {
BString s = fDevice->Host(); case PARAM_ENABLED:
*ioSize = MIN(*ioSize, s.Length()); // XXX
memcpy(value, s.String(), *ioSize); break;
return B_OK; case PARAM_HOST:
} {
if (id == fWebPortId) { BString s = fDevice->Host();
BString s; *ioSize = MIN(*ioSize, s.Length());
s << fDevice->Port(); memcpy(value, s.String(), *ioSize);
*ioSize = MIN(*ioSize, s.Length()); return B_OK;
memcpy(value, s.String(), *ioSize); }
return B_OK; case PARAM_PORT:
{
BString s;
s << fDevice->Port();
*ioSize = MIN(*ioSize, s.Length());
memcpy(value, s.String(), *ioSize);
return B_OK;
}
default:
break;
} }
#if 0 #if 0
BParameter *parameter = NULL; BParameter *parameter = NULL;
@@ -1098,78 +1122,6 @@ ESDSinkNode::GetParameterValue(int32 id, bigtime_t* last_change, void* value, si
} }
#endif #endif
#if 0
if(!parameter) {
// Hmmm, we were asked for a parameter that we don't actually
// support. Report an error back to the caller.
PRINT(("\terror - asked for illegal parameter %ld\n", id));
return B_ERROR;
}
multi_mix_value_info MMVI;
multi_mix_value MMV[2];
int rval;
MMVI.values = MMV;
id = id - 100;
MMVI.item_count = 0;
if (*ioSize < sizeof(float))
return B_ERROR;
if(parameter->Type() == BParameter::B_CONTINUOUS_PARAMETER) {
MMVI.item_count = 1;
MMV[0].id = id;
if(parameter->CountChannels() == 2) {
if (*ioSize < 2*sizeof(float))
return B_ERROR;
MMVI.item_count = 2;
MMV[1].id = id + 1;
}
} else if(parameter->Type() == BParameter::B_DISCRETE_PARAMETER) {
MMVI.item_count = 1;
MMV[0].id = id;
}
if(MMVI.item_count > 0) {
rval = fDevice->DoGetMix(&MMVI);
if (B_OK != rval) {
fprintf(stderr, "Failed on DRIVER_GET_MIX\n");
} else {
if(parameter->Type() == BParameter::B_CONTINUOUS_PARAMETER) {
((float*)value)[0] = MMV[0].gain;
*ioSize = sizeof(float);
if(parameter->CountChannels() == 2) {
((float*)value)[1] = MMV[1].gain;
*ioSize = 2*sizeof(float);
}
for(uint32 i=0; i < (*ioSize/sizeof(float)); i++) {
PRINT(("B_CONTINUOUS_PARAMETER value[%i] : %f\n", i, ((float*)value)[i]));
}
} else if(parameter->Type() == BParameter::B_DISCRETE_PARAMETER) {
BDiscreteParameter *dparameter = (BDiscreteParameter*) parameter;
if(dparameter->CountItems()<=2) {
((int32*)value)[0] = (MMV[0].enable) ? 1 : 0;
} else {
((int32*)value)[0] = MMV[0].mux;
}
*ioSize = sizeof(int32);
for(uint32 i=0; i < (*ioSize/sizeof(int32)); i++) {
PRINT(("B_DISCRETE_PARAMETER value[%i] : %i\n", i, ((int32*)value)[i]));
}
}
}
}
return B_OK;
#endif
return EINVAL; return EINVAL;
} }
@@ -1184,70 +1136,40 @@ ESDSinkNode::SetParameterValue(int32 id, bigtime_t performance_time, const void*
if(parameter->ID() == id) if(parameter->ID() == id)
break; break;
} }
if (id == fWebHostId) { switch (id) {
fprintf(stderr, "set HOST: %s\n", (const char *)value); case PARAM_ENABLED:
BString host = (const char *)value; break;
uint16 port = fDevice->Port(); case PARAM_HOST:
fDevice->Connect(host.String(), port); {
return; fprintf(stderr, "set HOST: %s\n", (const char *)value);
} fHostname = (const char *)value;
if (id == fWebPortId) { if (fDevice && fDevice->Connected()) {
fprintf(stderr, "set PORT: %s\n", (const char *)value); if (fDevice->Connect(fHostname.String(), fPort) >= 0) {
BString host = fDevice->Host(); fDevice->SetCommand();
uint16 port = atoi((const char *)value); fDevice->SetFormat(ESD_FMT, 2);
fDevice->Connect(host.String(), port); //fDevice->GetServerInfo();
return; fInitCheckStatus = fDevice->SendDefaultCommand();
} }
#if 0
if(parameter) {
multi_mix_value_info MMVI;
multi_mix_value MMV[2];
int rval;
MMVI.values = MMV;
id = id - 100;
MMVI.item_count = 0;
if(parameter->Type() == BParameter::B_CONTINUOUS_PARAMETER) {
for(uint32 i=0; i < (size/sizeof(float)); i++) {
PRINT(("B_CONTINUOUS_PARAMETER value[%i] : %f\n", i, ((float*)value)[i]));
}
MMVI.item_count = 1;
MMV[0].id = id;
MMV[0].gain = ((float*)value)[0];
if(parameter->CountChannels() == 2) {
MMVI.item_count = 2;
MMV[1].id = id + 1;
MMV[1].gain = ((float*)value)[1];
}
} else if(parameter->Type() == BParameter::B_DISCRETE_PARAMETER) {
for(uint32 i=0; i < (size/sizeof(int32)); i++) {
PRINT(("B_DISCRETE_PARAMETER value[%i] : %i\n", i, ((int32*)value)[i]));
}
BDiscreteParameter *dparameter = (BDiscreteParameter*) parameter;
if(dparameter->CountItems()<=2) {
MMVI.item_count = 1;
MMV[0].id = id;
MMV[0].enable = (((int32*)value)[0] == 1) ? true : false;
} else {
MMVI.item_count = 1;
MMV[0].id = id;
MMV[0].mux = ((uint32*)value)[0];
} }
return;
} }
case PARAM_PORT:
if(MMVI.item_count > 0) { {
rval = fDevice->DoSetMix(&MMVI); fprintf(stderr, "set PORT: %s\n", (const char *)value);
fPort = atoi((const char *)value);
if (B_OK != rval) if (fDevice && fDevice->Connected()) {
{ if (fDevice->Connect(fHostname.String(), fPort) >= 0) {
fprintf(stderr, "Failed on DRIVER_SET_MIX\n"); fDevice->SetCommand();
fDevice->SetFormat(ESD_FMT, 2);
//fDevice->GetServerInfo();
fInitCheckStatus = fDevice->SendDefaultCommand();
}
} }
return;
} }
default:
break;
} }
#endif
} }
BParameterWeb* BParameterWeb*
@@ -1276,12 +1198,12 @@ ESDSinkNode::MakeParameterWeb()
int id = 0; int id = 0;
BParameterGroup *group = web->MakeGroup("Server"); BParameterGroup *group = web->MakeGroup("Server");
BParameter *p; BParameter *p;
fWebHostId = fWebPortId = -1; // XXX: use B_MEDIA_UNKNOWN_TYPE or _NO_TYPE ?
// keep in sync with enum { PARAM_* } !
p = group->MakeDiscreteParameter(PARAM_ENABLED, B_MEDIA_RAW_AUDIO, "Enable", B_ENABLE);
#if defined(B_BEOS_VERSION_DANO) || defined(__HAIKU__) #if defined(B_BEOS_VERSION_DANO) || defined(__HAIKU__)
fWebHostId = id++; p = group->MakeTextParameter(PARAM_HOST, B_MEDIA_RAW_AUDIO, "Hostname", B_GENERIC, 128);
p = group->MakeTextParameter(fWebHostId, B_MEDIA_RAW_AUDIO, "Hostname", B_GENERIC, 128); p = group->MakeTextParameter(PARAM_PORT, B_MEDIA_RAW_AUDIO, "Port", B_GENERIC, 16);
fWebPortId = id++;
p = group->MakeTextParameter(fWebPortId, B_MEDIA_RAW_AUDIO, "Port", B_GENERIC, 16);
#endif #endif
return web; return web;
} }
@@ -52,6 +52,13 @@
const media_format & producer_format, const media_format & producer_format,
const media_format & consumer_format);*/ const media_format & consumer_format);*/
enum {
PARAM_ENABLED,
PARAM_HOST,
PARAM_PORT
};
class ESDSinkNode : class ESDSinkNode :
public BBufferConsumer, public BBufferConsumer,
#if ENABLE_INPUT #if ENABLE_INPUT
@@ -345,6 +352,7 @@ private:
thread_id fThread; thread_id fThread;
BString fHostname; BString fHostname;
uint16 fPort;
ESDEndpoint *fDevice; ESDEndpoint *fDevice;
//multi_description MD; //multi_description MD;
@@ -357,8 +365,6 @@ private:
bool fTimeSourceStarted; bool fTimeSourceStarted;
BParameterWeb *fWeb; BParameterWeb *fWeb;
int32 fWebHostId;
int32 fWebPortId;
BMessage fConfig; BMessage fConfig;
}; };