- 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 "ESDEndpoint.h"
ESDEndpoint::ESDEndpoint()
: BDataIO()
, fHost(NULL)
@@ -56,6 +57,7 @@ ESDEndpoint::ESDEndpoint()
Reset();
}
ESDEndpoint::~ESDEndpoint()
{
CALLED();
@@ -64,8 +66,18 @@ ESDEndpoint::~ESDEndpoint()
fSocket = -1;
}
void ESDEndpoint::Reset()
status_t
ESDEndpoint::InitCheck() const
{
return fInitStatus;
}
void
ESDEndpoint::Reset()
{
fInitStatus = B_NO_INIT;
fDefaultCommand = ESD_PROTO_STREAM_PLAY;
fDefaultCommandSent = false;
fDefaultFormat = ESD_BITS8 | ESD_MONO;
@@ -73,7 +85,9 @@ void ESDEndpoint::Reset()
fLatency = 0LL;
}
status_t ESDEndpoint::SendAuthKey()
status_t
ESDEndpoint::SendAuthKey()
{
CALLED();
BPath kfPath;
@@ -106,13 +120,49 @@ status_t ESDEndpoint::SendAuthKey()
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;
int flag;
CALLED();
fHost = host;
fPort = port;
struct hostent *he;
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));
PRINT(("connect: %s\n", strerror(err)));
PRINT(("connect: %ld, %s\n", err, strerror(errno)));
if (err < 0)
return errno;
@@ -220,17 +270,17 @@ status_t ESDEndpoint::Connect(const char *host, uint16 port)
setsockopt(fSocket, SOL_SOCKET, SO_SNDBUF, &flag, sizeof(flag));
*/
// read(fSocket, &ok, sizeof(uint32));
// connect
// auth
// ask server latency
// calc network latency (time (send+recv) / 2) ?
// get default format
// TODO: get default format
fInitStatus = B_OK;
return B_OK;
}
status_t ESDEndpoint::Disconnect()
status_t
ESDEndpoint::Disconnect()
{
CALLED();
if (fSocket > -1)
@@ -239,7 +289,8 @@ status_t ESDEndpoint::Disconnect()
return B_OK;
}
status_t ESDEndpoint::SetCommand(esd_command_t cmd)
status_t
ESDEndpoint::SetCommand(esd_command_t cmd)
{
CALLED();
if (fDefaultCommandSent)
@@ -248,7 +299,8 @@ status_t ESDEndpoint::SetCommand(esd_command_t cmd)
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;
CALLED();
@@ -282,7 +334,8 @@ status_t ESDEndpoint::SetFormat(int bits, int channels, float rate)
return B_OK;
}
status_t ESDEndpoint::GetServerInfo()
status_t
ESDEndpoint::GetServerInfo()
{
CALLED();
struct serverinfo {
@@ -298,19 +351,22 @@ status_t ESDEndpoint::GetServerInfo()
return B_OK;
}
bool ESDEndpoint::CanSend()
bool
ESDEndpoint::CanSend()
{
CALLED();
return fDefaultCommandSent;
}
ssize_t ESDEndpoint::Read(void *buffer, size_t size)
ssize_t
ESDEndpoint::Read(void *buffer, size_t size)
{
CALLED();
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;
CALLED();
@@ -336,7 +392,8 @@ ssize_t ESDEndpoint::Write(const void *buffer, size_t size)
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;
CALLED();
@@ -358,7 +415,8 @@ status_t ESDEndpoint::SendCommand(esd_command_t cmd, const uint8 *obuf, size_t o
return err;
}
status_t ESDEndpoint::SendDefaultCommand()
status_t
ESDEndpoint::SendDefaultCommand()
{
status_t err;
struct {
@@ -44,8 +44,11 @@ public:
~ESDEndpoint();
/* */
status_t InitCheck() const;
void Reset();
status_t SendAuthKey();
bool Connected() const;
status_t Connect(const char *host, uint16 port=ESD_DEFAULT_PORT);
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 SendDefaultCommand();
private:
static int32 _ConnectThread(void *_arg);
int32 ConnectThread(void);
status_t fInitStatus;
thread_id fConnectThread;
BString fHost;
uint16 fPort;
int fSocket;
@@ -133,9 +133,11 @@ ESDSinkNode::ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config)
config->FindString("hostname", &fHostname);
}
if (fHostname.Length() < 1)
fHostname = "192.168.0.253";
fHostname = "192.168.0.1";
fPort = ESD_DEFAULT_PORT;
fDevice = new ESDEndpoint();
/*
if (fDevice) {
if (fDevice->Connect(fHostname.String()) >= 0) {
fDevice->SetCommand();
@@ -144,6 +146,10 @@ ESDSinkNode::ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config)
fInitCheckStatus = fDevice->SendDefaultCommand();
}
}
*/
if (!fDevice)
return;
fInitCheckStatus = B_OK;
}
status_t ESDSinkNode::InitCheck(void) const
@@ -432,6 +438,15 @@ status_t ESDSinkNode::Connected(
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
fInternalLatency = with_format.u.raw_audio.buffer_size * 10000 / 2
/ ( (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)
return B_ERROR;
//PRINT(("id : %i\n", id));
if (id == fWebHostId) {
BString s = fDevice->Host();
*ioSize = MIN(*ioSize, s.Length());
memcpy(value, s.String(), *ioSize);
return B_OK;
}
if (id == fWebPortId) {
BString s;
s << fDevice->Port();
*ioSize = MIN(*ioSize, s.Length());
memcpy(value, s.String(), *ioSize);
return B_OK;
switch (id) {
case PARAM_ENABLED:
// XXX
break;
case PARAM_HOST:
{
BString s = fDevice->Host();
*ioSize = MIN(*ioSize, s.Length());
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
BParameter *parameter = NULL;
@@ -1098,78 +1122,6 @@ ESDSinkNode::GetParameterValue(int32 id, bigtime_t* last_change, void* value, si
}
#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;
}
@@ -1184,70 +1136,40 @@ ESDSinkNode::SetParameterValue(int32 id, bigtime_t performance_time, const void*
if(parameter->ID() == id)
break;
}
if (id == fWebHostId) {
fprintf(stderr, "set HOST: %s\n", (const char *)value);
BString host = (const char *)value;
uint16 port = fDevice->Port();
fDevice->Connect(host.String(), port);
return;
}
if (id == fWebPortId) {
fprintf(stderr, "set PORT: %s\n", (const char *)value);
BString host = fDevice->Host();
uint16 port = atoi((const char *)value);
fDevice->Connect(host.String(), port);
return;
}
#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];
switch (id) {
case PARAM_ENABLED:
break;
case PARAM_HOST:
{
fprintf(stderr, "set HOST: %s\n", (const char *)value);
fHostname = (const char *)value;
if (fDevice && fDevice->Connected()) {
if (fDevice->Connect(fHostname.String(), fPort) >= 0) {
fDevice->SetCommand();
fDevice->SetFormat(ESD_FMT, 2);
//fDevice->GetServerInfo();
fInitCheckStatus = fDevice->SendDefaultCommand();
}
}
return;
}
if(MMVI.item_count > 0) {
rval = fDevice->DoSetMix(&MMVI);
if (B_OK != rval)
{
fprintf(stderr, "Failed on DRIVER_SET_MIX\n");
case PARAM_PORT:
{
fprintf(stderr, "set PORT: %s\n", (const char *)value);
fPort = atoi((const char *)value);
if (fDevice && fDevice->Connected()) {
if (fDevice->Connect(fHostname.String(), fPort) >= 0) {
fDevice->SetCommand();
fDevice->SetFormat(ESD_FMT, 2);
//fDevice->GetServerInfo();
fInitCheckStatus = fDevice->SendDefaultCommand();
}
}
return;
}
default:
break;
}
#endif
}
BParameterWeb*
@@ -1276,12 +1198,12 @@ ESDSinkNode::MakeParameterWeb()
int id = 0;
BParameterGroup *group = web->MakeGroup("Server");
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__)
fWebHostId = id++;
p = group->MakeTextParameter(fWebHostId, B_MEDIA_RAW_AUDIO, "Hostname", B_GENERIC, 128);
fWebPortId = id++;
p = group->MakeTextParameter(fWebPortId, B_MEDIA_RAW_AUDIO, "Port", B_GENERIC, 16);
p = group->MakeTextParameter(PARAM_HOST, B_MEDIA_RAW_AUDIO, "Hostname", B_GENERIC, 128);
p = group->MakeTextParameter(PARAM_PORT, B_MEDIA_RAW_AUDIO, "Port", B_GENERIC, 16);
#endif
return web;
}
@@ -52,6 +52,13 @@
const media_format & producer_format,
const media_format & consumer_format);*/
enum {
PARAM_ENABLED,
PARAM_HOST,
PARAM_PORT
};
class ESDSinkNode :
public BBufferConsumer,
#if ENABLE_INPUT
@@ -345,6 +352,7 @@ private:
thread_id fThread;
BString fHostname;
uint16 fPort;
ESDEndpoint *fDevice;
//multi_description MD;
@@ -357,8 +365,6 @@ private:
bool fTimeSourceStarted;
BParameterWeb *fWeb;
int32 fWebHostId;
int32 fWebPortId;
BMessage fConfig;
};