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 0c7452885e..85453e1d38 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 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -142,12 +143,25 @@ ESDEndpoint::Connect(const char *host, uint16 port) err = resume_thread(fConnectThread); // TODO: return now instead and move Connect() call - wait_for_thread(fConnectThread, &err); + //wait_for_thread(fConnectThread, &err); return err; } +status_t +ESDEndpoint::WaitForConnect() +{ + status_t err; + int32 ret; + err = wait_for_thread(fConnectThread, &ret); + if (err < B_OK) + return err; + + return ret; +} + + int32 ESDEndpoint::_ConnectThread(void *_arg) { @@ -162,6 +176,9 @@ ESDEndpoint::ConnectThread(void) uint16 port = fPort; status_t err; int flag; + struct timeval oldTimeout; + socklen_t oldTimeoutLen = sizeof(struct timeval); + struct timeval timeout = { 10, 0 }; // 10s should be enough on a LAN CALLED(); struct hostent *he; @@ -188,9 +205,14 @@ ESDEndpoint::ConnectThread(void) setsockopt(fSocket, SOL_SOCKET, SO_SNDBUF, &flag, sizeof(flag)); setsockopt(fSocket, SOL_SOCKET, SO_RCVBUF, &flag, sizeof(flag)); */ + + if (getsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&oldTimeout, &oldTimeoutLen) >= 0) { + setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval)); + } err = connect(fSocket, (struct sockaddr *) &sin, sizeof(sin)); PRINT(("connect: %ld, %s\n", err, strerror(errno))); + setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&oldTimeout, sizeof(struct timeval)); if (err < 0) return errno; @@ -217,7 +239,7 @@ ESDEndpoint::ConnectThread(void) err = write(fSocket, &cmd, sizeof(cmd)); if (err < 0) return errno; - if (err < sizeof(cmd)) + if ((unsigned)err < sizeof(cmd)) return EIO; read(fSocket, &result, sizeof(result)); @@ -240,7 +262,7 @@ ESDEndpoint::ConnectThread(void) err = write(fSocket, &cmd, sizeof(cmd)); if (err < 0) return errno; - if (err < sizeof(cmd)) + if ((unsigned)err < sizeof(cmd)) return EIO; read(fSocket, &result, sizeof(result)); @@ -257,7 +279,7 @@ ESDEndpoint::ConnectThread(void) flag = 1; - int len; + //int len; /* disable Nagle */ setsockopt(fSocket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); //setsockopt(fSocket, SOL_SOCKET, SO_NONBLOCK, &flag, sizeof(flag)); @@ -306,7 +328,7 @@ ESDEndpoint::SetFormat(int bits, int channels, float rate) CALLED(); if (fDefaultCommandSent) return EALREADY; - PRINT(("SetFormat(%d,%d,%d)\n", bits, channels, rate)); + PRINT(("SetFormat(%d,%d,%f)\n", bits, channels, rate)); switch (bits) { case 8: fmt |= ESD_BITS8; @@ -328,7 +350,7 @@ ESDEndpoint::SetFormat(int bits, int channels, float rate) return EINVAL; } fmt |= ESD_STREAM | ESD_FUNC_PLAY; - PRINT(("SetFormat: %08lx\n", fmt)); + PRINT(("SetFormat: %08lx\n", (long)fmt)); fDefaultFormat = fmt; fDefaultRate = rate; return B_OK; @@ -347,10 +369,20 @@ ESDEndpoint::GetServerInfo() err = SendCommand(ESD_PROTO_SERVER_INFO, (const uint8 *)&si, 0, (uint8 *)&si, sizeof(si)); if (err < 0) return err; - PRINT(("err %d, version: %lu, rate: %lu, fmt: %lu\n", err, si.ver, si.rate, si.fmt)); + PRINT(("err 0x%08lx, version: %lu, rate: %lu, fmt: %lu\n", err, si.ver, si.rate, si.fmt)); return B_OK; } + +void +ESDEndpoint::GetFriendlyName(BString &name) +{ + name = "ESounD Out"; + name << " (" << Host(); + name << ":" << Port() << ")"; + +} + bool ESDEndpoint::CanSend() { @@ -381,8 +413,8 @@ ESDEndpoint::Write(const void *buffer, size_t size) size *= 2; } err = write(fSocket, buffer, size); - if (err != size) { - fprintf(stderr, "ESDEndpoint::Write: sent only %d of %d!\n", err, size); + if ((unsigned)err != size) { + fprintf(stderr, "ESDEndpoint::Write: sent only %ld of %ld!\n", err, size); if (err < 0) fprintf(stderr, "ESDEndpoint::Write: %s\n", strerror(errno)); } 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 76800548d8..31e74d8d6e 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 @@ -50,6 +50,7 @@ status_t SendAuthKey(); bool Connected() const; status_t Connect(const char *host, uint16 port=ESD_DEFAULT_PORT); +status_t WaitForConnect(); status_t Disconnect(); /* set the default command and format for BDataIO interface */ @@ -63,6 +64,7 @@ status_t GetServerInfo(); bigtime_t GetLatency() const { return fLatency; }; const char *Host() const { return fHost.String(); }; uint16 Port() const { return fPort; }; +void GetFriendlyName(BString &name); bool CanSend(); diff --git a/src/add-ons/media/media-add-ons/esound_sink/ESDSinkAddOn.cpp b/src/add-ons/media/media-add-ons/esound_sink/ESDSinkAddOn.cpp index 305cfc5cad..e2c3e1933e 100644 --- a/src/add-ons/media/media-add-ons/esound_sink/ESDSinkAddOn.cpp +++ b/src/add-ons/media/media-add-ons/esound_sink/ESDSinkAddOn.cpp @@ -119,12 +119,11 @@ status_t ESDSinkAddOn::GetFlavorAt( return B_BAD_INDEX; } - ESDEndpoint *device = (ESDEndpoint *) fDevices.ItemAt(n); + //ESDEndpoint *device = (ESDEndpoint *) fDevices.ItemAt(n); flavor_info * infos = new flavor_info[1]; ESDSinkNode::GetFlavor(&infos[0], n); // infos[0].name = device->MD.friendly_name; - infos[0].name = "ESounD Out"; (*out_info) = infos; return B_OK; } @@ -136,16 +135,20 @@ BMediaNode * ESDSinkAddOn::InstantiateNodeFor( { CALLED(); + BString name = "ESounD Sink"; #ifdef MULTI_SAVE - if(fSettings.FindMessage(device->MD.friendly_name, config)==B_OK) { - fSettings.RemoveData(device->MD.friendly_name); + ESDEndpoint *device = (ESDEndpoint *) fDevices.ItemAt(info->internal_id); + if (device) + device->GetFriendlyName(name); + if(fSettings.FindMessage(name.String(), config)==B_OK) { + fSettings.RemoveData(name.String()); } #endif ESDSinkNode * node = new ESDSinkNode(this, - "ESounD Sink", + (char *)name.String(), config); if (node == 0) { *out_error = B_NO_MEMORY; @@ -161,7 +164,8 @@ ESDSinkAddOn::GetConfigurationFor(BMediaNode * your_node, BMessage * into_messag { CALLED(); #ifdef MULTI_SAVE - into_message = new BMessage(); + if (!into_message) + into_message = new BMessage(); ESDSinkNode * node = dynamic_cast(your_node); if (node == 0) { fprintf(stderr,"<- B_BAD_TYPE\n"); @@ -173,13 +177,15 @@ ESDSinkAddOn::GetConfigurationFor(BMediaNode * your_node, BMessage * into_messag return B_OK; #endif // currently never called by the media kit. Seems it is not implemented. - +#if 0 ESDSinkNode * node = dynamic_cast(your_node); if (node == 0) { fprintf(stderr,"<- B_BAD_TYPE\n"); return B_BAD_TYPE; } return node->GetConfigurationFor(into_message); +#endif + return B_ERROR; } #if 0 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 6b154e1a38..bc82c4260d 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 @@ -28,6 +28,7 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ +//#define DEBUG 4 #include #include #include @@ -58,15 +59,6 @@ #include #include -const char * multi_string[] = -{ - "NAME IS ATTACHED", - "Output", "Input", "Setup", "Tone Control", "Extended Setup", "Enhanced Setup", "Master", - "Beep", "Phone", "Mic", "Line", "CD", "Video", "Aux", "Wave", "Gain", "Level", "Volume", - "Mute", "Enable", "Stereo Mix", "Mono Mix", "Output Stereo Mix", "Output Mono Mix", "Output Bass", - "Output Treble", "Output 3D Center", "Output 3D Depth" -}; - // -------------------------------------------------------- // // ctor/dtor @@ -133,8 +125,9 @@ ESDSinkNode::ESDSinkNode(BMediaAddOn *addon, char* name, BMessage * config) config->FindString("hostname", &fHostname); } if (fHostname.Length() < 1) - fHostname = "192.168.0.1"; + fHostname = "172.20.109.151";//"192.168.0.2"; fPort = ESD_DEFAULT_PORT; + fEnabled = false; fDevice = new ESDEndpoint(); /* @@ -241,7 +234,7 @@ void ESDSinkNode::NodeRegistered(void) } #ifdef PRINTING - PRINT(("apply configuration in : %ld\n", system_time() - start)); + PRINT(("apply configuration in : %lld\n", system_time() - start)); #endif } @@ -266,6 +259,7 @@ status_t ESDSinkNode::AcceptFormat( const media_destination & dest, media_format * format) { + status_t err; CALLED(); if(fInput.destination != dest) { @@ -310,6 +304,10 @@ status_t ESDSinkNode::AcceptFormat( return B_MEDIA_BAD_FORMAT; }*/ //AddRequirements(format); + + // start connecting here + err = fDevice->Connect(fHostname.String(), fPort); + return B_OK; } @@ -322,7 +320,7 @@ status_t ESDSinkNode::GetNextInput( if ((*cookie < 1) && (*cookie >= 0)) { *out_input = fInput; *cookie += 1; - PRINT(("input.format : %u\n", fInput.format.u.raw_audio.format)); + PRINT(("input.format : %lu\n", fInput.format.u.raw_audio.format)); return B_OK; } else return B_BAD_INDEX; @@ -431,6 +429,7 @@ status_t ESDSinkNode::Connected( const media_format & with_format, media_input * out_input) { + status_t err; CALLED(); if(fInput.destination != where) { @@ -440,12 +439,15 @@ status_t ESDSinkNode::Connected( // if (fDevice) { - if (fDevice->Connect(fHostname.String(), fPort) >= 0) { - fDevice->SetCommand(); - //fDevice->GetServerInfo(); - fDevice->SetFormat(ESD_FMT, 2); - fInitCheckStatus = fDevice->SendDefaultCommand(); - } + err = fDevice->WaitForConnect(); + if (err < B_OK) + return err; + fDevice->SetCommand(); + //fDevice->GetServerInfo(); + fDevice->SetFormat(ESD_FMT, 2); + err = fDevice->SendDefaultCommand(); + if (err < B_OK) + return err; } // use one buffer length latency fInternalLatency = with_format.u.raw_audio.buffer_size * 10000 / 2 @@ -483,6 +485,8 @@ void ESDSinkNode::Disconnected( fInput.source = media_source::null; fInput.format = fPreferredFormat; //GetFormat(&channel->fInput.format); + if (fDevice) + fDevice->Disconnect(); } /* The notification comes from the upstream producer, so he's already cool with */ @@ -957,7 +961,7 @@ status_t ESDSinkNode::HandleDataStatus( bool realTimeEvent) { CALLED(); - PRINT(("ESDSinkNode::HandleDataStatus status:%li, lateness:%li\n", event->data, lateness)); + PRINT(("ESDSinkNode::HandleDataStatus status:%li, lateness:%lli\n", event->data, lateness)); switch(event->data) { case B_DATA_NOT_AVAILABLE: break; @@ -1093,8 +1097,11 @@ ESDSinkNode::GetParameterValue(int32 id, bigtime_t* last_change, void* value, si //PRINT(("id : %i\n", id)); switch (id) { case PARAM_ENABLED: - // XXX - break; + if (*ioSize < sizeof(bool)) + return B_NO_MEMORY; + *(bool *)value = fEnabled; + *ioSize = sizeof(bool); + return B_OK; case PARAM_HOST: { BString s = fDevice->Host(); @@ -1129,7 +1136,7 @@ void ESDSinkNode::SetParameterValue(int32 id, bigtime_t performance_time, const void* value, size_t size) { CALLED(); - PRINT(("id : %i, performance_time : %lld, size : %i\n", id, performance_time, size)); + PRINT(("id : %li, performance_time : %lld, size : %li\n", id, performance_time, size)); BParameter *parameter = NULL; for(int32 i=0; iCountParameters(); i++) { parameter = fWeb->ParameterAt(i); @@ -1138,11 +1145,15 @@ ESDSinkNode::SetParameterValue(int32 id, bigtime_t performance_time, const void* } switch (id) { case PARAM_ENABLED: - break; + if (size != sizeof(bool)) + return; + fEnabled = *(bool *)value; + return; case PARAM_HOST: { fprintf(stderr, "set HOST: %s\n", (const char *)value); fHostname = (const char *)value; +#if 0 if (fDevice && fDevice->Connected()) { if (fDevice->Connect(fHostname.String(), fPort) >= 0) { fDevice->SetCommand(); @@ -1151,12 +1162,14 @@ ESDSinkNode::SetParameterValue(int32 id, bigtime_t performance_time, const void* fInitCheckStatus = fDevice->SendDefaultCommand(); } } +#endif return; } case PARAM_PORT: { fprintf(stderr, "set PORT: %s\n", (const char *)value); fPort = atoi((const char *)value); +#if 0 if (fDevice && fDevice->Connected()) { if (fDevice->Connect(fHostname.String(), fPort) >= 0) { fDevice->SetCommand(); @@ -1165,6 +1178,7 @@ ESDSinkNode::SetParameterValue(int32 id, bigtime_t performance_time, const void* fInitCheckStatus = fDevice->SendDefaultCommand(); } } +#endif return; } default: @@ -1177,25 +1191,6 @@ ESDSinkNode::MakeParameterWeb() { CALLED(); BParameterWeb* web = new BParameterWeb; -#if 0 - PRINT(("MMCI.control_count : %i\n", fDevice->MMCI.control_count)); - multi_mix_control *MMC = fDevice->MMCI.controls; - - for(int i=0; iMMCI.control_count; i++) { - if(MMC[i].flags & B_MULTI_MIX_GROUP && MMC[i].parent == 0) { - PRINT(("NEW_GROUP\n")); - int32 nb = 0; - const char* childName; - if(MMC[i].string != S_null) - childName = multi_string[MMC[i].string]; - else - childName = MMC[i].name; - BParameterGroup *child = web->MakeGroup(childName); - ProcessGroup(child, i, nb); - } - } -#endif - int id = 0; BParameterGroup *group = web->MakeGroup("Server"); BParameter *p; // XXX: use B_MEDIA_UNKNOWN_TYPE or _NO_TYPE ? @@ -1207,93 +1202,7 @@ ESDSinkNode::MakeParameterWeb() #endif return web; } -#if 0 -void -ESDSinkNode::ProcessGroup(BParameterGroup *group, int32 index, int32 &nbParameters) -{ - CALLED(); - multi_mix_control *parent = &fDevice->MMCI.controls[index]; - multi_mix_control *MMC = fDevice->MMCI.controls; - for(int32 i=0; iMMCI.control_count; i++) { - if(MMC[i].parent != parent->id) - continue; - - const char* childName; - if(MMC[i].string != S_null) - childName = multi_string[MMC[i].string]; - else - childName = MMC[i].name; - - if(MMC[i].flags & B_MULTI_MIX_GROUP) { - PRINT(("NEW_GROUP\n")); - int32 nb = 1; - BParameterGroup *child = group->MakeGroup(childName); - child->MakeNullParameter(MMC[i].id, B_MEDIA_RAW_AUDIO, childName, B_WEB_BUFFER_OUTPUT); - ProcessGroup(child, i, nb); - } else if(MMC[i].flags & B_MULTI_MIX_MUX) { - PRINT(("NEW_MUX\n")); - BDiscreteParameter *parameter = - group->MakeDiscreteParameter(100 + MMC[i].id, B_MEDIA_RAW_AUDIO, childName, B_INPUT_MUX); - if(nbParameters>0) { - (group->ParameterAt(nbParameters - 1))->AddOutput(group->ParameterAt(nbParameters)); - nbParameters++; - } - ProcessMux(parameter, i); - } else if(MMC[i].flags & B_MULTI_MIX_GAIN) { - PRINT(("NEW_GAIN\n")); - group->MakeContinuousParameter(100 + MMC[i].id, B_MEDIA_RAW_AUDIO, "", B_MASTER_GAIN, - "dB", MMC[i].gain.min_gain, MMC[i].gain.max_gain, MMC[i].gain.granularity); - - if(i+1 MMCI.control_count && MMC[i+1].master == MMC[i].id && MMC[i+1].flags & B_MULTI_MIX_GAIN) { - group->ParameterAt(nbParameters)->SetChannelCount( - group->ParameterAt(nbParameters)->CountChannels() + 1); - i++; - } - - PRINT(("nb parameters : %d\n", nbParameters)); - if (nbParameters > 0) { - (group->ParameterAt(nbParameters - 1))->AddOutput(group->ParameterAt(nbParameters)); - nbParameters++; - } - } else if(MMC[i].flags & B_MULTI_MIX_ENABLE) { - PRINT(("NEW_ENABLE\n")); - if(MMC[i].string == S_MUTE) - group->MakeDiscreteParameter(100 + MMC[i].id, B_MEDIA_RAW_AUDIO, childName, B_MUTE); - else - group->MakeDiscreteParameter(100 + MMC[i].id, B_MEDIA_RAW_AUDIO, childName, B_ENABLE); - if(nbParameters>0) { - (group->ParameterAt(nbParameters - 1))->AddOutput(group->ParameterAt(nbParameters)); - nbParameters++; - } - } - } -} -void -ESDSinkNode::ProcessMux(BDiscreteParameter *parameter, int32 index) -{ - CALLED(); - multi_mix_control *parent = &fDevice->MMCI.controls[index]; - multi_mix_control *MMC = fDevice->MMCI.controls; - int32 itemIndex = 0; - for(int32 i=0; iMMCI.control_count; i++) { - if(MMC[i].parent != parent->id) - continue; - - const char* childName; - if(MMC[i].string != S_null) - childName = multi_string[MMC[i].string]; - else - childName = MMC[i].name; - - if(MMC[i].flags & B_MULTI_MIX_MUX_VALUE) { - PRINT(("NEW_MUX_VALUE\n")); - parameter->AddItem(itemIndex, childName); - itemIndex++; - } - } -} -#endif // -------------------------------------------------------- // // ESDSinkNode specific functions // -------------------------------------------------------- // @@ -1309,6 +1218,9 @@ ESDSinkNode::GetConfigurationFor(BMessage * into_message) bigtime_t last_change; status_t err; + if (!into_message) + return B_BAD_VALUE; + buffer = malloc(size); for(int32 i=0; iCountParameters(); i++) { @@ -1317,7 +1229,7 @@ ESDSinkNode::GetConfigurationFor(BMessage * into_message) && parameter->Type() != BParameter::B_DISCRETE_PARAMETER) continue; - PRINT(("getting parameter %i\n", parameter->ID())); + PRINT(("getting parameter %li\n", parameter->ID())); size = 128; while((err = GetParameterValue(parameter->ID(), &last_change, buffer, &size))==B_NO_MEMORY) { size += 128; @@ -1329,7 +1241,7 @@ ESDSinkNode::GetConfigurationFor(BMessage * into_message) into_message->AddInt32("parameterID", parameter->ID()); into_message->AddData("parameterData", B_RAW_TYPE, buffer, size, false); } else { - PRINT(("parameter err : %s\n", strerror(err))); + PRINT(("parameter %li err : %s\n", parameter->ID(), strerror(err))); } } 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 b39820bc5c..4fbb0a324e 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 @@ -353,6 +353,7 @@ private: BString fHostname; uint16 fPort; + bool fEnabled; ESDEndpoint *fDevice; //multi_description MD; diff --git a/src/add-ons/media/media-add-ons/esound_sink/Jamfile b/src/add-ons/media/media-add-ons/esound_sink/Jamfile index 94a5360a1d..6e45d95d48 100644 --- a/src/add-ons/media/media-add-ons/esound_sink/Jamfile +++ b/src/add-ons/media/media-add-ons/esound_sink/Jamfile @@ -6,14 +6,10 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) { SubDirC++Flags -fmultiple-symbol-spaces ; } -Addon ESDSink.media_addon : +Addon esound_sink.media_addon : ESDEndpoint.cpp ESDSinkAddOn.cpp ESDSinkNode.cpp : be media network $(TARGET_LIBSUPC++) ; -#Package haiku-multi_audio-cvs -# : hmulti_audio.media_addon -# : boot home config add-ons media ; -