From cbd43babfe8568bdddd6d3f776aa50c93f890c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Sun, 17 Aug 2008 18:37:23 +0000 Subject: [PATCH] - 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 --- .../media-add-ons/esound_sink/ESDEndpoint.cpp | 100 ++++++-- .../media-add-ons/esound_sink/ESDEndpoint.h | 10 +- .../media-add-ons/esound_sink/ESDSinkNode.cpp | 220 ++++++------------ .../media-add-ons/esound_sink/ESDSinkNode.h | 10 +- 4 files changed, 167 insertions(+), 173 deletions(-) diff --git a/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.cpp b/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.cpp index 4189b62927..0c7452885e 100644 --- a/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.cpp +++ b/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.cpp @@ -46,6 +46,7 @@ #include #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 { diff --git a/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.h b/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.h index e6968f4b82..76800548d8 100644 --- a/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.h +++ b/src/add-ons/media/media-add-ons/esound_sink/ESDEndpoint.h @@ -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; diff --git a/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.cpp b/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.cpp index 7ca08901fe..6b154e1a38 100644 --- a/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.cpp +++ b/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.cpp @@ -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; } diff --git a/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.h b/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.h index bf6ee2bdf4..b39820bc5c 100644 --- a/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.h +++ b/src/add-ons/media/media-add-ons/esound_sink/ESDSinkNode.h @@ -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; };