Exemple #1
0
static	void veejay_add_arguments_ ( lo_message lmsg, const char *format, va_list ap )
{
	//http://liblo.sourceforge.net/docs/group__liblolowlevel.html#g31ac1e4c0ec6c61f665ce3f9bbdc53c3
	while( *format != 'x' && *format != '\0' )
	{
		switch(*format)
		{
			case 'i':
				lo_message_add_int32( lmsg, (int32_t) va_arg( ap, int));
				break;
			case 'h':
				lo_message_add_int64( lmsg, (int64_t) va_arg( ap, int64_t));
				break;
			case 's':
				{  char *str = (char*) va_arg(ap,char*);
				lo_message_add_string( lmsg, str ); }
				break;
			case 'd':
	//			double g =  (double) *(va_arg(ap, double*));
				{	double g = (double) va_arg(ap,double);
				lo_message_add_double( lmsg, g); }
				break;
			default:
				break;
		}
		*format ++;
	}
}
Exemple #2
0
//=========================================================
void io_simple_long(char *path, uint64_t l)
{
	if(io_())
	{
		lo_message msgio=lo_message_new();
		lo_message_add_int64(msgio, l);
		lo_send_message(loio, path, msgio);
		lo_message_free(msgio);
	}
}
Exemple #3
0
void	veejay_bundle_sample_add_fx_atom( void *osc, int id,int entry, const char *word, const char *format, int type, void *value )
{
	char osc_path[256];
	oscclient_t *c = (oscclient_t*) osc;
	if(!c->bundle)
	{
		c->bundle = lo_bundle_new( LO_TT_IMMEDIATE );
	}

	sprintf(osc_path, "/sample_%d/fx_%d/%s", id, entry,word );
	lo_message lmsg = lo_message_new();
	char realwin[128];
	sprintf(realwin, "%sFX%d", c->window, entry );
	lo_message_add_string(lmsg, realwin );
	lo_message_add_string(lmsg, osc_path );

	int ival;
	char *str;
	double gval;
	uint64_t val;
	switch(type)
	{
		case VEVO_ATOM_TYPE_STRING:
			str = (char*) *( (char*) value);
			lo_message_add_string( lmsg, str );
			break;
		case VEVO_ATOM_TYPE_BOOL:
		case VEVO_ATOM_TYPE_INT:
			ival = (int) *( (int*) value );
			lo_message_add_int32( lmsg, ival );
			break;
		case VEVO_ATOM_TYPE_DOUBLE:
			gval = (double) *( (double*) value );
			lo_message_add_double( lmsg, gval );
			break;
		case VEVO_ATOM_TYPE_UINT64:
			val = (uint64_t) *( (uint64_t*) value );
			lo_message_add_int64( lmsg, (int64_t) val );
			break;
		default:
			lo_message_free( lmsg );
			return;
			break;
	}

	lo_bundle_add_message( c->bundle,"/update/widget", lmsg );

}
Exemple #4
0
void	veejay_bundle_add_atom( void *osc, const char *osc_path, const char *format, int type, void *value )
{
	oscclient_t *c = (oscclient_t*) osc;
	if(!c->bundle)
	{
		c->bundle = lo_bundle_new( LO_TT_IMMEDIATE );
	}

	lo_message lmsg = lo_message_new();
	lo_message_add_string( lmsg,c->window );
	lo_message_add_string( lmsg,osc_path );

	int ival;
	char *str;
	double gval;
	uint64_t val;
	switch(type)
	{
		case VEVO_ATOM_TYPE_STRING:
			str = (char*) *( (char*) value);
			lo_message_add_string( lmsg, str );
			break;
		case VEVO_ATOM_TYPE_BOOL:
		case VEVO_ATOM_TYPE_INT:
			ival = (int) *( (int*) value );
			lo_message_add_int32( lmsg, ival );
			break;
		case VEVO_ATOM_TYPE_DOUBLE:
			gval = (double) *( (double*) value );
			lo_message_add_double( lmsg, gval );
			break;
		case VEVO_ATOM_TYPE_UINT64:
			val = (uint64_t) *( (uint64_t*) value );
			lo_message_add_int64( lmsg, (int64_t) val );
			break;
		default:
			lo_message_free( lmsg );
			return;
			break;
	}

	lo_bundle_add_message( c->bundle, "/update/widget", lmsg );

}
Exemple #5
0
void	veejay_bundle_plugin_add( void *osc, const char *window, const char *path, const char *format, void *value )
{
	oscclient_t *c = (oscclient_t*) osc;
	if(!c->bundle)
		c->bundle = lo_bundle_new( LO_TT_IMMEDIATE );

	lo_message lmsg = lo_message_new();

	lo_message_add_string(lmsg, window );
	lo_message_add_string(lmsg, path );

	int n_elem = strlen( format );
	int ival;
	char *str;
	double gval;
	uint64_t val;
	
	switch(*format)
	{
		case 's':
			str = (char*) *( (char*) value);
			lo_message_add_string( lmsg, str );
			break;
		case 'i':
			ival = (int) *( (int*) value );
			lo_message_add_int32( lmsg, ival );
			break;
		case 'd':
			gval = (double) *( (double*) value );
			lo_message_add_double( lmsg, gval );
			break;
		case 'h':
			val = (uint64_t) *( (uint64_t*) value );
			lo_message_add_int64( lmsg, (int64_t) val );
			break;
		default:
			lo_message_free( lmsg );
			return;
			break;
	}

	lo_bundle_add_message( c->bundle,"/update/widget", lmsg );
}
Exemple #6
0
//this is not a JACK process cylce
int process()
{
	if(shutdown_in_progress==1)
	{
		return 0;
	}

	if(process_enabled==1)
	{

		//as long as there is data ready to be sent, read and try to send
		//need: handle case where receiver can not read data fast enough
//		while(rb_can_read(rb)
//			>=input_port_count*bytes_per_sample*period_size)
//		{

		while(rb_can_read(rb)
			>=port_count*bytes_per_sample*period_size)
		{
			//fake consume
//			rb_advance_read_pointer(rb,port_count*bytes_per_sample*period_size);

			lo_message mm=lo_message_new();

			//add message counter
			lo_message_add_int64(mm,message_number_out);

			//indicate how many xruns (in sender's JACK)
			lo_message_add_int64(mm,remote_xrun_counter);

			gettimeofday(&tv, NULL);
			lo_timetag tt;
			tt.sec=(long)tv.tv_sec;
			tt.frac=(long)tv.tv_usec;
			lo_message_add_timetag(mm,tt);
			lo_message_add_int32(mm,sample_rate);


			//blob array, holding one period per channel
//			lo_blob blob[input_port_count];
			lo_blob blob[port_count];

			void* membuf = malloc(period_size*bytes_per_sample);

			int i;
			for( i=0; i<port_count; i++ )
			{
				//void* membuf = malloc(period_size*bytes_per_sample);
				rb_read (rb, (char*)membuf, period_size*bytes_per_sample);
				blob[i]=lo_blob_new(period_size*bytes_per_sample,membuf);
				lo_message_add_blob(mm,blob[i]);
			}
			int ret=lo_send_message(loa_tcp,"/audio",mm);
			last_lo_send_message_tcp_return=ret;

			if(ret<0)
			{
//				fprintf(stderr," TCP WARN: msg no: %" PRId64 " size: %" PRId64 " ret: %d ",message_number_out,lo_message_length(mm,"/audio"),ret);
			}
			else
			{
				total_bytes_successfully_sent+=ret;

//				fprintf(stderr," msg no: %" PRId64 " size: %" PRId64 " ret: %d ",message_number_out,lo_message_length(mm,"/audio"),ret);
				message_number_out++;
			}

			//free
			//lo_free(membuf);
			lo_message_free(mm);
			free(membuf);
			//free blobls ...
			for( i=0; i<port_count; i++ )
			{
				free(blob[i]);
			}

			if(ret<0)
			{
				return ret;
			}


		}//end while has data

		return 0;

	}//end if process enabled
	//process not yet enabled, buffering
	else
	{
		if(relaxed_display_counter>=update_display_every_nth_cycle
			|| last_test_cycle==1
		)
		{
			if((int)message_number<=0 && starting_transmission==0)
			{
				fprintf(stderr,"\rwaiting for audio input data...");
			}

			fflush(stderr);

			relaxed_display_counter=0;
		}
		relaxed_display_counter++;

	return 0;

	}//end if process not enabled

	//return 0;



} //end process
Exemple #7
0
void moNetOSCOut::SendDataMessage( int i, moDataMessage &datamessage ) {
#ifdef OSCPACK
    if (packetStream==NULL) {
        cout << "moNetOSCOut::SendDataMessage > error: packetStream is NULL" << endl;
        return;
    }
#endif

	//cout << "moNetOSCOut::SendDataMessage > start" << endl;
#ifdef OSCPACK
	packetStream->Clear();
	//cout << "moNetOSCOut::SendDataMessage > Clear() ok." << endl;

    (*packetStream) << osc::BeginBundleImmediate;
    //cout << "moNetOSCOut::SendDataMessage > BeginBundleImmediate ok." << endl;

    (*packetStream) << osc::BeginMessage( moText("")+ IntToStr(datamessage.Count()) );
    //cout << "moNetOSCOut::SendDataMessage > data in messages:" << datamessage.Count() << endl;
#else
lo_timetag timetag;
lo_timetag_now(&timetag);
lo_bundle bundle = lo_bundle_new(timetag);
lo_message ms = lo_message_new();
moText oscpath = "";
#endif
    moData data;
    int nfields = 0;
    int error = 0;
    try {
      for(int j=0; j< datamessage.Count(); j++) {
          data = datamessage[j];
          if (debug_is_on) MODebug2->Message( moText("moNetOSCOut::SendDataMessage "+GetLabelName()+" > data:") + IntToStr(j) );
          switch(data.Type()) {
          #ifdef OSCPACK
              case MO_DATA_NUMBER_FLOAT:
                  (*packetStream) << data.Float();
                  break;
              case MO_DATA_NUMBER_INT:
                  (*packetStream) << data.Int();
                  break;
              case MO_DATA_NUMBER_LONG:
                  (*packetStream) << data.Long();
                  break;
              case MO_DATA_NUMBER_DOUBLE:
                  (*packetStream) << data.Double();
                  break;
              case MO_DATA_TEXT:
                  (*packetStream) << (char*)data.Text();
                  break;
          #else
              case MO_DATA_NUMBER_FLOAT:
                  error = lo_message_add_float( ms , data.Float());
                  nfields++;
                  break;
              case MO_DATA_NUMBER_INT:
                  error = lo_message_add_int32( ms , data.Int());
                  nfields++;
                  break;
              case MO_DATA_NUMBER_LONG:
                  error = lo_message_add_int64( ms , data.Long());
                  nfields++;
                  break;
              case MO_DATA_NUMBER_DOUBLE:
                  error = lo_message_add_double( ms , data.Double());
                  nfields++;
                  break;
              case MO_DATA_TEXT:
                  if (oscpath=="") {
                    oscpath = data.Text();
                    moText mot = data.Text().Left(50000);
                    error = lo_message_add_string( ms , (char*)mot);
                    nfields++;
                  } else {
                    moText mot = data.Text().Left(50000);
                    error = lo_message_add_string( ms , (char*)mot);
                    nfields++;
                  }
                  break;

          #endif


          }
        if (error<0)
          MODebug2->Error(moText("moNetOSCOut > data error adding value: ") + data.ToText() );
      }
#ifdef OSCPACK
    } catch(osc::Exception E) {
      MODebug2->Error( moText("moNetOSCOut > Exception: ") + E.what()
                      + " packet actual size: (" + IntToStr( (*packetStream).Size() ) + ") "
                      + " Data too long for buffer: (max OUTPUT_BUFFER_SIZE:" + IntToStr(OUTPUT_BUFFER_SIZE) + ") "
                      + data.ToText()
                      + " (size:"+ IntToStr(data.ToText().Length())+" )"
                      + " (total size:" + IntToStr( data.ToText().Length() + (*packetStream).Size() ) + ")" );
    }
  (*packetStream) << osc::EndMessage;
    //cout << "moNetOSCOut::SendDataMessage > osc::EndMessage ok" << endl;
    //cout << "osc::EndBundle: " << endl;
    //cout << osc::EndBundle << endl;

    #ifdef MO_WIN32
        (*packetStream) << osc::EndBundle;
    #endif
    //cout << "moNetOSCOut::SendDataMessage > osc::EndBundle ok" << endl;

    //cout << "moNetOSCOut::SendDataMessage > sending." << endl;

    if (transmitSockets[i]) {
        //MODebug2->Message(moText("moNetOSCOut > sending ") + IntToStr(i) + " size:" + IntToStr(packetStream->Size()) );
        transmitSockets[i]->Send( packetStream->Data(), packetStream->Size() );

    }
#else
    } catch(...) {
Exemple #8
0
static int osc_send(CSOUND *csound, OSCSEND *p)
{
    /* Types I allow at present:
       0) int
       1) float
       2) string
       3) double
       4) char
       5) table as blob
    */
    if (p->cnt++ ==0 || *p->kwhen!=p->last) {
      int i=0;
      int msk = 0x20;           /* First argument */
      lo_message msg = lo_message_new();
      char *type = (char*)p->type->data;
      MYFLT **arg = p->arg;
      p->last = *p->kwhen;
      for (i=0; type[i]!='\0'; i++, msk <<=1) {
        /* Need to add type checks */
        switch (type[i]) {
        case 'i':
          lo_message_add_int32(msg, (int32_t) MYFLT2LRND(*arg[i]));
          break;
        case 'l':
          lo_message_add_int64(msg, (int64_t) MYFLT2LRND(*arg[i]));
          break;
        case 'c':
          lo_message_add_char(msg, (char) (*arg[i] + FL(0.5)));
          break;
        case 'm':
          {
            union a {
              int32_t  x;
              uint8_t  m[4];
            } mm;
            mm.x = *arg[i]+FL(0.5);
            lo_message_add_midi(msg, mm.m);
            break;
          }
        case 'f':
          lo_message_add_float(msg, (float)(*arg[i]));
          break;
        case 'd':
          lo_message_add_double(msg, (double)(*arg[i]));
          break;
        case 's':
            lo_message_add_string(msg, ((STRINGDAT *)arg[i])->data);
          break;
        case 'b':               /* Boolean */
          if (*arg[i]==FL(0.0)) lo_message_add_true(msg);
          else lo_message_add_false(msg);
          break;
        case 't':               /* timestamp */
          {
            lo_timetag tt;
            tt.sec = (uint32_t)(*arg[i]+FL(0.5));
            msk <<= 1; i++;
            if (UNLIKELY(type[i]!='t'))
              return csound->PerfError(csound, p->h.insdshead,
                                       Str("Time stamp is two values"));
            tt.frac = (uint32_t)(*arg[i]+FL(0.5));
            lo_message_add_timetag(msg, tt);
            break;
          }
          //#ifdef SOMEFINEDAY
        case 'T':               /* Table/blob */
          {
            lo_blob myblob;
            int     len;
            FUNC    *ftp;
            void *data;
            /* make sure fn exists */
            if (LIKELY((ftp=csound->FTnp2Find(csound,arg[i]))!=NULL)) {
              data = ftp->ftable;
              len = ftp->flen-1;        /* and set it up */
            }
            else {
              return csound->PerfError(csound, p->h.insdshead,
                                       Str("ftable %.2f does not exist"), *arg[i]);
            }
            myblob = lo_blob_new(sizeof(MYFLT)*len, data);
            lo_message_add_blob(msg, myblob);
            lo_blob_free(myblob);
            break;
          }
          //#endif
        default:
          csound->Warning(csound, Str("Unknown OSC type %c\n"), type[1]);
        }
      }
      lo_send_message(p->addr, (char*)p->dest->data, msg);
      lo_message_free(msg);
    }
    return OK;
}
Exemple #9
0
static int osc_send(CSOUND *csound, OSCSEND *p)
{
    /* Types I allow at present:
       0) int
       1) float
       2) string
       3) double
       4) char
       5) table as blob
    */
    char port[8];
    char *pp = port;
    char *hh;

    if (*p->port<0)
      pp = NULL;
    else
      snprintf(port, 8, "%d", (int) MYFLT2LRND(*p->port));
    hh = (char*) p->host->data;
    if (*hh=='\0') hh = NULL;
    if(p->addr != NULL)
      lo_address_free(p->addr);
    p->addr = lo_address_new(hh, pp);

    if (p->cnt++ ==0 || *p->kwhen!=p->last) {
      int i=0;
      int msk = 0x20;           /* First argument */
      lo_message msg = lo_message_new();
      char *type = (char*)p->type->data;
      MYFLT **arg = p->arg;
      p->last = *p->kwhen;
      for (i=0; type[i]!='\0'; i++, msk <<=1) {
        /* Need to add type checks */
        switch (type[i]) {
        case 'i':
          lo_message_add_int32(msg, (int32_t) MYFLT2LRND(*arg[i]));
          break;
        case 'l':
        case 'h':
          lo_message_add_int64(msg, (int64_t) MYFLT2LRND(*arg[i]));
          break;
        case 'c':
          lo_message_add_char(msg, (char) (*arg[i] + FL(0.5)));
          break;
        case 'm':
          {
            union a {
              int32_t  x;
              uint8_t  m[4];
            } mm;
            mm.x = *arg[i]+FL(0.5);
            lo_message_add_midi(msg, mm.m);
            break;
          }
        case 'f':
          lo_message_add_float(msg, (float)(*arg[i]));
          break;
        case 'd':
          lo_message_add_double(msg, (double)(*arg[i]));
          break;
        case 's':
            lo_message_add_string(msg, ((STRINGDAT *)arg[i])->data);
          break;
        case 'b':               /* Boolean */
          if (*arg[i]==FL(0.0)) lo_message_add_true(msg);
          else lo_message_add_false(msg);
          break;
        case 't':               /* timestamp */
          {
            lo_timetag tt;
            tt.sec = (uint32_t)(*arg[i]+FL(0.5));
            msk <<= 1; i++;
            if (UNLIKELY(type[i]!='t'))
              return csound->PerfError(csound, p->h.insdshead,
                                       Str("Time stamp is two values"));
            tt.frac = (uint32_t)(*arg[i]+FL(0.5));
            lo_message_add_timetag(msg, tt);
            break;
          }
          //#ifdef SOMEFINEDAY
        case 'G':               /* fGen Table/blob */
          {
            lo_blob myblob;
            int     len, olen;
            FUNC    *ftp;
            void *data;
            /* make sure fn exists */
            if (LIKELY((ftp=csound->FTnp2Find(csound,arg[i]))!=NULL)) {
              len = ftp->flen;        /* and set it up */
              data = csound->Malloc(csound,
                                    olen=sizeof(FUNC)-sizeof(MYFLT*)+
                                         sizeof(MYFLT)*len);
              memcpy(data, ftp, sizeof(FUNC)-sizeof(MYFLT*));
              memcpy(data+sizeof(FUNC)-sizeof(MYFLT*),
                     ftp->ftable, sizeof(MYFLT)*len);
            }
            else {
              return csound->PerfError(csound, p->h.insdshead,
                                       Str("ftable %.2f does not exist"), *arg[i]);
            }
            myblob = lo_blob_new(olen, data);
            lo_message_add_blob(msg, myblob);
            csound->Free(csound, data);
            lo_blob_free(myblob);
            break;
          }
          //#endif
        case 'a':               /* Audio as blob */
          {
            lo_blob myblob;
            MYFLT *data = csound->Malloc(csound, sizeof(MYFLT)*(CS_KSMPS+1));
            data[0] = CS_KSMPS;
            memcpy(&data[1], arg[i], data[0]);
            myblob = lo_blob_new(sizeof(MYFLT)*(CS_KSMPS+1), data);
            lo_message_add_blob(msg, myblob);
            csound->Free(csound, data);
            lo_blob_free(myblob);
            break;
          }
        case 'A':               /* Array/blob */
          {
            lo_blob myblob;
            int     len = 1;
            ARRAYDAT *ss;
            /* make sure fn exists */
            if (LIKELY((ss = (ARRAYDAT*)arg[i]) !=NULL &&
                       ss->data != NULL)) {
              int j, d;
              for (j=0,d=ss->dimensions; d>0; j++, d--)
                len *= ss->sizes[j];
              len *= sizeof(MYFLT);
            }
            else {
              return csound->PerfError(csound, p->h.insdshead,
                                       Str("argument %d is not an array"), i);
            }
            // two parts needed
            {
              void *dd = malloc(len+sizeof(int)*(1+ss->dimensions));
              memcpy(dd, &ss->dimensions, sizeof(int));
              memcpy(dd+sizeof(int), ss->sizes, sizeof(int)*ss->dimensions);
              memcpy(dd+sizeof(int)*(1+ss->dimensions), ss->data, len);
      /* printf("dd length = %d dimensions = %d, %d %d %.8x %.8x %.8x %.8x\n", */
      /*        len+sizeof(int)*(1+ss->dimensions), ss->dimensions, */
      /*        ((int*)dd)[0], ((int*)dd)[1], ((int*)dd)[2], ((int*)dd)[3], */
      /*        ((int*)dd)[4], ((int*)dd)[5]); */
              myblob = lo_blob_new(len, dd);
              free(dd);
            }
            lo_message_add_blob(msg, myblob);
            lo_blob_free(myblob);
            break;
          }
        case 'S': csound->Warning(csound, "S unimplemented"); break;
          //#endif
        default:
          csound->Warning(csound, Str("Unknown OSC type %c\n"), type[1]);
        }
      }
      lo_send_message(p->addr, (char*)p->dest->data, msg);
      lo_message_free(msg);
    }
    return OK;
}
//================================================================
void print_info()
{
	uint64_t can_read_count=jack_ringbuffer_read_space(rb);

	char* offset_string;
	if(channel_offset>0)
	{
		asprintf(&offset_string, "(%d+)", (channel_offset));
	}
	else
	{
		offset_string="";
	}

	//this is per channel, not per cycle. *port_count
	if(relaxed_display_counter>=update_display_every_nth_cycle*port_count
		|| last_test_cycle==1
	)
	{

		if(shutup==0 && quiet==0)
		{
			fprintf(stderr,"\r# %" PRId64 " i: %s%d f: %.1f b: %" PRId64 " s: %.4f i: %.2f r: %" PRId64 
				" l: %" PRId64 " d: %" PRId64 " o: %" PRId64 " p: %.1f%s",
				message_number,
				offset_string,
				input_port_count,
				(float)can_read_count/(float)bytes_per_sample/(float)period_size/(float)port_count,
				can_read_count,
				(float)can_read_count/(float)port_count/(float)bytes_per_sample/(float)sample_rate,
				time_interval_avg*1000,
				remote_xrun_counter,
				local_xrun_counter,
				multi_channel_drop_counter,
				buffer_overflow_counter,
				(float)frames_since_cycle_start_avg/(float)period_size,
				"\033[0J"
			);
		}

		if(io_())
		{

			lo_message msgio=lo_message_new();

			lo_message_add_int64(msgio,message_number);
			lo_message_add_int32(msgio,input_port_count);
			lo_message_add_int32(msgio,channel_offset);

			lo_message_add_float(msgio,
				(float)can_read_count/(float)bytes_per_sample/(float)period_size/(float)port_count
			);

			lo_message_add_int64(msgio,can_read_count);

			lo_message_add_float(msgio,
				(float)can_read_count/(float)port_count/(float)bytes_per_sample/(float)sample_rate
			);

			lo_message_add_float(msgio,time_interval_avg*1000);
			lo_message_add_int64(msgio,remote_xrun_counter);
			lo_message_add_int64(msgio,local_xrun_counter);
			lo_message_add_int64(msgio,multi_channel_drop_counter);
			lo_message_add_int64(msgio,buffer_overflow_counter);

			lo_message_add_float(msgio,
				(float)frames_since_cycle_start_avg/(float)period_size
			);

			lo_send_message(loio, "/status", msgio);
			lo_message_free(msgio);
		}

		fflush(stderr);

		relaxed_display_counter=0;
	}
	relaxed_display_counter++;
}//end print_info
//================================================================
int process(jack_nframes_t nframes, void *arg)
{
	//fprintf(stderr,".");
	//return 0;

	//if shutting down fill buffers with 0 and return
	if(shutdown_in_progress==1)
	{
		int i;
		for(i=0; i < output_port_count; i++)
		{
			sample_t *o1;
			o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);
			//memset(o1, 0, bytes_per_sample*nframes);
			//always 4 bytes, 32 bit float
			memset(o1, 0, 4*nframes);
		}
		return 0;
	}

	if(process_enabled==1)
	{
		//if no data for this cycle(all channels) 
		//is available(!), fill buffers with 0 or re-use old buffers and return
		if(jack_ringbuffer_read_space(rb) < port_count * bytes_per_sample*nframes)
		{
			int i;
			for(i=0; i < output_port_count; i++)
			{
				if(shutdown_in_progress==1 || process_enabled!=1)
				{
					return 0;
				}

				if(zero_on_underflow==1)
				{
					sample_t *o1;
					o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);

					//memset(o1, 0, bytes_per_sample*nframes);
					//always 4 bytes, 32 bit float
					memset(o1, 0, 4*nframes);
				}
				print_info();
			}

			multi_channel_drop_counter++;

			if(rebuffer_on_underflow==1)
			{
				pre_buffer_counter=0;
				process_enabled=0;
			}

			//reset avg calculation
			time_interval_avg=0;
			msg_received_counter=0;
			fscs_avg_counter=0;

			return 0;
		}//end not enough data available in ringbuffer

		process_cycle_counter++;

		if(process_cycle_counter>receive_max-1 && test_mode==1)
		{
			last_test_cycle=1;
		}

		//init to 0. increment before use
		fscs_avg_counter++;

		frames_since_cycle_start_sum+=frames_since_cycle_start;
		frames_since_cycle_start_avg=frames_since_cycle_start_sum/fscs_avg_counter;

		//check and reset after use
		if(fscs_avg_calc_interval>=fscs_avg_counter)
		{
			fscs_avg_counter=0;
			frames_since_cycle_start_sum=0;	
		}

		//if sender sends more channels than we have output channels, ignore them
		int i;
		for(i=0; i<port_count; i++)
		{
			if(shutdown_in_progress==1 || process_enabled!=1)
			{
				return 0;
			}

			sample_t *o1;
			o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);

			int16_t *o1_16;

			if(bytes_per_sample==2)
			{
				o1_16=malloc(bytes_per_sample*nframes);
			}

			//32 bit float
			if(bytes_per_sample==4)
			{
				jack_ringbuffer_read(rb, (char*)o1, bytes_per_sample*nframes);
			}
			//16 bit pcm
			else
			{
				jack_ringbuffer_read(rb, (char*)o1_16, bytes_per_sample*nframes);

				int x;
				for(x=0;x<nframes;x++)
				{
					o1[x]=(float)MIN_(MAX_((float)o1_16[x]/32760,-1.0f),1.0f);
				}

				free(o1_16);
			}

			/*
			fprintf(stderr,"\rreceiving from %s:%s",
				sender_host,sender_port
			);
			*/

			print_info();

		}//end for i < port_count

		//requested via /buffer, for test purposes (make buffer "tight")
		if(requested_drop_count>0)
		{
			uint64_t drop_bytes_count=requested_drop_count
				*port_count*period_size*bytes_per_sample;

			jack_ringbuffer_read_advance(rb,drop_bytes_count);

			requested_drop_count=0;
			multi_channel_drop_counter=0;
		}
	}//end if process_enabled==1
	else //if process_enabled==0
	{
		int i;
		for(i=0; i<port_count; i++)
		{
			if(shutdown_in_progress==1 || process_enabled!=1)
			{
				return 0;
			}

			sample_t *o1;
			o1=(sample_t*)jack_port_get_buffer(ioPortArray[i], nframes);

			//this is per channel, not per cycle. *port_count
			if(relaxed_display_counter>=update_display_every_nth_cycle*port_count
				|| last_test_cycle==1
			)
			{
				//only for init
				if((int)message_number<=0 && starting_transmission==0)
				{
					if(shutup==0 && quiet==0)
					{
						fprintf(stderr,"\rwaiting for audio input data...");
					}
					io_simple("/wait_for_input");
				}
				else
				{
					if(shutup==0 && quiet==0)
					{
						fprintf(stderr,"\r# %" PRId64 " buffering... mc periods to go: %" PRId64 "%s",
							message_number,
							pre_buffer_size-pre_buffer_counter,
							"\033[0J"
						);
					}

					if(io_())
					{
						lo_message msgio=lo_message_new();

						lo_message_add_int64(msgio,message_number);
						lo_message_add_int64(msgio,pre_buffer_size-pre_buffer_counter);

						lo_send_message(loio, "/buffering", msgio);
						lo_message_free(msgio);
					}
				}

				fflush(stderr);

				relaxed_display_counter=0;
			}
			relaxed_display_counter++;

			//set output buffer silent
			//memset(o1, 0, port_count*bytes_per_sample*nframes);
			//always 4 bytes, 32 bit float
			memset(o1, 0, port_count*4*nframes);
		}//end for i < port_count
	}//end process_enabled==0

	//tasks independent of process_enabled 0/1

	//if sender sends less channels than we have output channels, wee need to fill them with 0
	if(input_port_count < output_port_count)
	{
		int i;
		for(i=0;i < (output_port_count-input_port_count);i++)
		{
			//sample_t *o1;
			//o1=(sample_t*)
			/////?
			jack_port_get_buffer(ioPortArray[input_port_count+i], nframes);
		}
	}

	if(last_test_cycle==1)
	{
		if(shutup==0)
		{
			fprintf(stderr,"\ntest finished after %" PRId64 " process cycles\n",process_cycle_counter);
			fprintf(stderr,"(waiting and buffering cycles not included)\n");
		}

		io_simple_long("/test_finished",process_cycle_counter);

		shutdown_in_progress=1;
	}

	//simulate long cycle process duration
	//usleep(1000);

	frames_since_cycle_start=jack_frames_since_cycle_start(client);

	return 0;
} //end process()
Exemple #12
0
int lo_message_add_varargs_internal(lo_message msg, const char *types,
                                    va_list ap, const char *file, int line)
{
    int count = 0;
    int ret = 0;

    while (types && *types) {
        count++;

        switch (*types++) {

        case LO_INT32:{
                int32_t i = va_arg(ap, int32_t);
                lo_message_add_int32(msg, i);
                break;
            }

        case LO_FLOAT:{
                float f = (float) va_arg(ap, double);
                lo_message_add_float(msg, f);
                break;
            }

        case LO_STRING:{
                char *s = va_arg(ap, char *);
#ifndef USE_ANSI_C
                if (s == (char *) LO_MARKER_A) {
                    fprintf(stderr,
                            "liblo error: lo_send or lo_message_add called with "
                            "invalid string pointer for arg %d, probably arg mismatch\n"
                            "at %s:%d, exiting.\n", count, file, line);
                }
#endif
                lo_message_add_string(msg, s);
                break;
            }

        case LO_BLOB:{
                lo_blob b = va_arg(ap, lo_blob);
                lo_message_add_blob(msg, b);
                break;
            }

        case LO_INT64:{
                int64_t i64 = va_arg(ap, int64_t);
                lo_message_add_int64(msg, i64);
                break;
            }

        case LO_TIMETAG:{
                lo_timetag tt = va_arg(ap, lo_timetag);
                lo_message_add_timetag(msg, tt);
                break;
            }

        case LO_DOUBLE:{
                double d = va_arg(ap, double);
                lo_message_add_double(msg, d);
                break;
            }

        case LO_SYMBOL:{
                char *s = va_arg(ap, char *);
#ifndef USE_ANSI_C
                if (s == (char *) LO_MARKER_A) {
                    fprintf(stderr,
                            "liblo error: lo_send or lo_message_add called with "
                            "invalid symbol pointer for arg %d, probably arg mismatch\n"
                            "at %s:%d, exiting.\n", count, file, line);
                    va_end(ap);
                    return -2;
                }
#endif
                lo_message_add_symbol(msg, s);
                break;
            }

        case LO_CHAR:{
                char c = va_arg(ap, int);
                lo_message_add_char(msg, c);
                break;
            }

        case LO_MIDI:{
                uint8_t *m = va_arg(ap, uint8_t *);
                lo_message_add_midi(msg, m);
                break;
            }

        case LO_TRUE:
            lo_message_add_true(msg);
            break;

        case LO_FALSE:
            lo_message_add_false(msg);
            break;

        case LO_NIL:
            lo_message_add_nil(msg);
            break;

        case LO_INFINITUM:
            lo_message_add_infinitum(msg);
            break;

        case '$':
            if (*types == '$') {
                // type strings ending in '$$' indicate not to perform
                // LO_MARKER checking
                va_end(ap);
                return 0;
            }
            // fall through to unknown type

        default:{
                ret = -1;       // unknown type
                fprintf(stderr,
                        "liblo warning: unknown type '%c' at %s:%d\n",
                        *(types - 1), file, line);
                break;
            }
        }
    }
#ifndef USE_ANSI_C
    void *i = va_arg(ap, void *);
    if (((unsigned long)i & 0xFFFFFFFFUL)
	!= ((unsigned long)LO_MARKER_A & 0xFFFFFFFFUL))
    {
        ret = -2;               // bad format/args
        fprintf(stderr,
                "liblo error: lo_send, lo_message_add, or lo_message_add_varargs called with "
                "mismatching types and data at\n%s:%d, exiting.\n", file,
                line);
        va_end(ap);
        return ret;
    }
    i = va_arg(ap, void *);
    if (((unsigned long)i & 0xFFFFFFFFUL)
	!= ((unsigned long)LO_MARKER_B & 0xFFFFFFFFUL))
    {
        ret = -2;               // bad format/args
        fprintf(stderr,
                "liblo error: lo_send, lo_message_add, or lo_message_add_varargs called with "
                "mismatching types and data at\n%s:%d, exiting.\n", file,
                line);
    }
#endif
    va_end(ap);

    return ret;
}
Exemple #13
0
void test_deserialise()
{
    char *buf, *buf2, *tmp;
    const char *types = NULL, *path;
    lo_arg **argv = NULL;
    size_t len, size;
    char data[256];
    int result = 0;

    lo_blob btest = lo_blob_new(sizeof(testdata), testdata);
    uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00};
    lo_timetag tt = {0x1, 0x80000000};
    lo_blob b = NULL;

    // build a message
    lo_message msg = lo_message_new();
    TEST(0 == lo_message_get_argc(msg));
    lo_message_add_float(msg, 0.12345678f);             // 0  f
    lo_message_add_int32(msg, 123);                     // 1  i
    lo_message_add_string(msg, "123");                  // 2  s
    lo_message_add_blob(msg, btest);                    // 3  b
    lo_message_add_midi(msg, midi_data);                // 4  m
    lo_message_add_int64(msg, 0x0123456789abcdefULL);   // 5  h
    lo_message_add_timetag(msg, tt);                    // 6  t
    lo_message_add_double(msg, 0.9999);                 // 7  d
    lo_message_add_symbol(msg, "sym");                  // 8  S
    lo_message_add_char(msg, 'X');                      // 9  c
    lo_message_add_char(msg, 'Y');                      // 10 c
    lo_message_add_true(msg);                           // 11 T
    lo_message_add_false(msg);                          // 12 F
    lo_message_add_nil(msg);                            // 13 N
    lo_message_add_infinitum(msg);                      // 14 I

    // test types, args
    TEST(15 == lo_message_get_argc(msg));
    types = lo_message_get_types(msg);
    TEST(NULL != types);
    argv = lo_message_get_argv(msg);
    TEST(NULL != argv);
    TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON);
    TEST('i' == types[1] && 123 == argv[1]->i);
    TEST('s' == types[2] && !strcmp(&argv[2]->s, "123"));
    TEST('b' == types[3]);
    b = (lo_blob)argv[3];
    TEST(lo_blob_datasize(b) == sizeof(testdata));
    TEST(12 == lo_blobsize(b));
    TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata)));
    TEST('m' == types[4]  && !memcmp(&argv[4]->m, midi_data, 4));
    TEST('h' == types[5]  && 0x0123456789abcdefULL == argv[5]->h);
    TEST('t' == types[6]  && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac);
    TEST('d' == types[7]  && fabs(argv[7]->d - 0.9999) < FLT_EPSILON);
    TEST('S' == types[8]  && !strcmp(&argv[8]->s, "sym"));
    TEST('c' == types[9]  && 'X' == argv[9]->c);
    TEST('c' == types[10] && 'Y' == argv[10]->c);
    TEST('T' == types[11] && NULL == argv[11]);
    TEST('F' == types[12] && NULL == argv[12]);
    TEST('N' == types[13] && NULL == argv[13]);
    TEST('I' == types[14] && NULL == argv[14]);

    // serialise it
    len = lo_message_length(msg, "/foo");
    printf("serialise message_length=%d\n", (int)len);
    buf = calloc(len, sizeof(char));
    size = 0;
    tmp = lo_message_serialise(msg, "/foo", buf, &size);
    TEST(tmp == buf && size == len && 92 == len);
    lo_message_free(msg);

    // deserialise it
    printf("deserialise\n");
    path = lo_get_path(buf, len);
    TEST(NULL != path && !strcmp(path, "/foo"));
    msg = lo_message_deserialise(buf, size, NULL);
    TEST(NULL != msg);

    // repeat same test as above
    TEST(15 == lo_message_get_argc(msg));
    types = lo_message_get_types(msg);
    TEST(NULL != types);
    argv = lo_message_get_argv(msg);
    TEST(NULL != argv);
    TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON);
    TEST('i' == types[1] && 123 == argv[1]->i);
    TEST('s' == types[2] && !strcmp(&argv[2]->s, "123"));
    TEST('b' == types[3]);
    b = (lo_blob)argv[3];
    TEST(lo_blob_datasize(b) == sizeof(testdata));
    TEST(12 == lo_blobsize(b));
    TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata)));
    TEST('m' == types[4]  && !memcmp(&argv[4]->m, midi_data, 4));
    TEST('h' == types[5]  && 0x0123456789abcdefULL == argv[5]->h);
    TEST('t' == types[6]  && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac);
    TEST('d' == types[7]  && fabs(argv[7]->d - 0.9999) < FLT_EPSILON);
    TEST('S' == types[8]  && !strcmp(&argv[8]->s, "sym"));
    TEST('c' == types[9]  && 'X' == argv[9]->c);
    TEST('c' == types[10] && 'Y' == argv[10]->c);
    TEST('T' == types[11] && NULL == argv[11]);
    TEST('F' == types[12] && NULL == argv[12]);
    TEST('N' == types[13] && NULL == argv[13]);
    TEST('I' == types[14] && NULL == argv[14]);

    // serialise it again, compare
    len = lo_message_length(msg, "/foo");
    printf("serialise message_length=%d\n", (int)len);
    buf2 = calloc(len, sizeof(char));
    size = 0;
    tmp = lo_message_serialise(msg, "/foo", buf2, &size);
    TEST(tmp == buf2 && size == len && 92 == len);
    TEST(!memcmp(buf, buf2, len));
    lo_message_free(msg);

    lo_blob_free(btest);
    free(buf);
    free(buf2);

    // deserialise failure tests with invalid message data

    msg = lo_message_deserialise(data, 0, &result); // 0 size
    TEST(NULL == msg && LO_ESIZE == result);

    snprintf(data, 256, "%s", "/foo"); // unterminated path string
    msg = lo_message_deserialise(data, 4, &result);
    TEST(NULL == msg && LO_EINVALIDPATH == result);

    snprintf(data, 256, "%s", "/f_o"); // non-0 in pad area
    msg = lo_message_deserialise(data, 4, &result);
    TEST(NULL == msg && LO_EINVALIDPATH == result);

    snprintf(data, 256, "%s", "/t__"); // types missing
    replace_char(data, 4, '_', '\0');
    msg = lo_message_deserialise(data, 4, &result);
    TEST(NULL == msg && LO_ENOTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", "____"); // types empty
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 8, &result);
    TEST(NULL == msg && LO_EBADTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", ",f_"); // short message
    replace_char(data, 7, '_', '\0');
    msg = lo_message_deserialise(data, 7, &result);
    TEST(NULL == msg && LO_EINVALIDTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", "ifi_"); // types missing comma
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 8, &result);
    TEST(NULL == msg && LO_EBADTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", ",ifi"); // types unterminated
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 8, &result);
    TEST(NULL == msg && LO_EINVALIDTYPE == result);

    snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 12, &result);
    TEST(NULL == msg && LO_EINVALIDARG == result);

    snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data again
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 15, &result);
    TEST(NULL == msg && LO_EINVALIDARG == result);

    snprintf(data, 256, "%s%s", "/t__", ",f__"); // too much arg data
    replace_char(data, 8, '_', '\0');
    msg = lo_message_deserialise(data, 16, &result);
    TEST(NULL == msg && LO_ESIZE == result);

    snprintf(data, 256, "%s%s", "/t__", ",bs_"); // blob longer than msg length
    replace_char(data, 8, '_', '\0');
    *(uint32_t *)(data + 8) = lo_htoo32((uint32_t)99999);
    msg = lo_message_deserialise(data, 256, &result);
    TEST(NULL == msg && LO_EINVALIDARG == result);
}
Exemple #14
0
int main(int argc, char **argv)
{
    int i, j, result = 0;

    // process flags for -v verbose, -h help
    for (i = 1; i < argc; i++) {
        if (argv[i] && argv[i][0] == '-') {
            int len = strlen(argv[i]);
            for (j = 1; j < len; j++) {
                switch (argv[i][j]) {
                    case 'h':
                        eprintf("testdatabase.c: possible arguments "
                                "-q quiet (suppress output), "
                                "-h help\n");
                        return 1;
                        break;
                    case 'q':
                        verbose = 0;
                        break;
                    default:
                        break;
                }
            }
        }
    }

    lo_message lom;
    mapper_message msg;
    uint64_t id = 1;
    mapper_network net = mapper_network_new(0, 0, 0);
    mapper_database db = &net->database;

    mapper_device dev, *pdev, *pdev2;
    mapper_signal sig, *psig, *psig2;
    mapper_map *pmap, *pmap2;

    /* Test the database functions */

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 1234);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "localhost");
    lo_message_add_string(lom, "@num_inputs");
    lo_message_add_int32(lom, 2);
    lo_message_add_string(lom, "@num_outputs");
    lo_message_add_int32(lom, 2);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 1234);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "localhost");
    lo_message_add_string(lom, "@num_inputs");
    lo_message_add_int32(lom, 2);
    lo_message_add_string(lom, "@num_outputs");
    lo_message_add_int32(lom, 1);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase__.2", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 3000);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "192.168.0.100");

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase.3", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@port");
    lo_message_add_int32(lom, 5678);
    lo_message_add_string(lom, "@host");
    lo_message_add_string(lom, "192.168.0.100");

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_device(db, "testdatabase__.4", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "input");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "in1", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "input");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "in2", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "output");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "out1", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "output");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "out2", "testdatabase.1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@direction");
    lo_message_add_string(lom, "output");
    lo_message_add_string(lom, "@type");
    lo_message_add_char(lom, 'f');
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    mapper_database_add_or_update_signal(db, "out1", "testdatabase__.2", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "bypass");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "none");
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    const char *src_sig_name = "testdatabase.1/out2";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase__.2/in1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "bypass");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "none");
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    src_sig_name = "testdatabase__.2/out1";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase.1/in1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "expression");
    lo_message_add_string(lom, "@expression");
    lo_message_add_string(lom, "(x-10)*80");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "clamp");
    lo_message_add_string(lom, "@src@min");
    lo_message_add_float(lom, 0.f);
    lo_message_add_float(lom, 1.f);
    lo_message_add_string(lom, "@src@max");
    lo_message_add_float(lom, 1.f);
    lo_message_add_float(lom, 2.f);
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    src_sig_name = "testdatabase.1/out1";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase__.2/in2", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    lom = lo_message_new();
    if (!lom) {
        result = 1;
        goto done;
    }

    id++;
    lo_message_add_string(lom, "@mode");
    lo_message_add_string(lom, "expression");
    lo_message_add_string(lom, "@expression");
    lo_message_add_string(lom, "(x-10)*80");
    lo_message_add_string(lom, "@dst@bound_min");
    lo_message_add_string(lom, "clamp");
    lo_message_add_string(lom, "@src@min");
    lo_message_add_float(lom, 0.f);
    lo_message_add_float(lom, 1.f);
    lo_message_add_string(lom, "@src@max");
    lo_message_add_float(lom, 1.f);
    lo_message_add_float(lom, 2.f);
    lo_message_add_string(lom, "@id");
    lo_message_add_int64(lom, id);

    if (!(msg = mapper_message_parse_properties(lo_message_get_argc(lom),
                                                lo_message_get_types(lom),
                                                lo_message_get_argv(lom)))) {
        eprintf("1: Error, parsing failed.\n");
        result = 1;
        goto done;
    }

    src_sig_name = "testdatabase.1/out1";
    mapper_database_add_or_update_map(db, 1, &src_sig_name,
                                      "testdatabase__.2/in1", msg);

    mapper_message_free(msg);
    lo_message_free(lom);

    /*********/

    if (verbose) {
        eprintf("Dump:\n");
        mapper_database_print(db);
    }

    /*********/

    eprintf("\n--- Devices ---\n");

    eprintf("\nWalk the whole database:\n");
    pdev = mapper_database_devices(db);
    int count=0;
    if (!pdev) {
        eprintf("mapper_database_devices() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices() returned something "
               "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 4) {
        eprintf("Expected 4 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind device named 'testdatabase.3':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.3");
    if (!dev) {
        eprintf("Not found.\n");
        result = 1;
        goto done;
    }

    printdevice(dev);

    /*********/

    eprintf("\nFind device named 'dummy':\n");

    dev = mapper_database_device_by_name(db, "dummy");
    if (dev) {
        eprintf("unexpected found 'dummy': %p\n", dev);
        result = 1;
        goto done;
    }
    eprintf("  not found, good.\n");

    /*********/

    eprintf("\nFind devices matching '__':\n");

    pdev = mapper_database_devices_by_name(db, "*__*");

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with property 'host'=='192.168.0.100':\n");

    pdev = mapper_database_devices_by_property(db, "host", 1, 's',
                                               "192.168.0.100", MAPPER_OP_EQUAL);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with property 'port'<5678:\n");

    int port = 5678;
    pdev = mapper_database_devices_by_property(db, "port", 1, 'i', &port,
                                               MAPPER_OP_LESS_THAN);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 3) {
        eprintf("Expected 3 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with property 'num_outputs'==2:\n");
    int temp = 2;
    pdev = mapper_database_devices_by_property(db, "num_outputs", 1, 'i', &temp,
                                               MAPPER_OP_EQUAL);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 1) {
        eprintf("Expected 1 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind devices with properties 'host'!='localhost' AND 'port'>=4000:\n");

    pdev = mapper_database_devices_by_property(db, "host", 1, 's', "localhost",
                                               MAPPER_OP_NOT_EQUAL);
    pdev2 = mapper_database_devices_by_property(db, "port", 1, 'i', &port,
                                                MAPPER_OP_GREATER_THAN_OR_EQUAL);
    pdev = mapper_device_query_intersection(pdev, pdev2);

    count=0;
    if (!pdev) {
        eprintf("mapper_database_devices_by_property() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pdev) {
        eprintf("mapper_database_devices_by_property() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pdev) {
        count ++;
        printdevice(*pdev);
        pdev = mapper_device_query_next(pdev);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\n--- Signals ---\n");

    eprintf("\nFind all signals for device 'testdatabase.1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);

    count=0;
    if (!psig) {
        eprintf("mapper_device_signals() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("mapper_device_signals() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 4) {
        eprintf("Expected 4 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind all signals for device 'testdatabase__xx.2':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__xx.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);

    count=0;
    if (psig) {
        eprintf("mapper_device_signals() incorrectly found something.\n");
        printsignal(*psig);
        mapper_signal_query_done(psig);
        result = 1;
        goto done;
    }
    else
        eprintf("  correctly returned 0.\n");

    /*********/

    eprintf("\nFind all outputs for device 'testdatabase__.2':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);

    count=0;
    if (!psig) {
        eprintf("mapper_device_signals() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("mapper_device_signals() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 3) {
        eprintf("Expected 3 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind signal matching 'in' for device 'testdatabase.1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*in*");
    psig = mapper_signal_query_intersection(psig, psig2);

    count=0;
    if (!psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind signal matching 'out' for device 'testdatabase.1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*out*");
    psig = mapper_signal_query_intersection(psig, psig2);

    count=0;
    if (!psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind signal matching 'out' for device 'testdatabase__.2':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*out*");
    psig = mapper_signal_query_intersection(psig, psig2);

    count=0;
    if (!psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*psig) {
        eprintf("intersection of mapper_device_signals() and "
                "mapper_database_signals_by_name() returned something "
                "which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (psig) {
        count ++;
        printsignal(*psig);
        psig = mapper_signal_query_next(psig);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\n--- maps ---\n");

    eprintf("\nFind maps with source 'out1':\n");

    psig = mapper_database_signals_by_name(db, "out1");
    pmap = 0;
    while (psig) {
        pmap2 = mapper_signal_maps(*psig, MAPPER_DIR_OUTGOING);
        pmap = mapper_map_query_union(pmap, pmap2);
        psig = mapper_signal_query_next(psig);
    }

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 3) {
        eprintf("Expected 3 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for device 'testdatabase.1', source 'out1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase.1");
    sig = mapper_device_signal_by_name(dev, "out1");
    pmap = mapper_signal_maps(sig, 0);

    count=0;
    if (!pmap) {
        eprintf("mapper_signal_maps() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("mapper_signal_maps() returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps with destination signal named 'in2':\n");

    psig = mapper_database_signals_by_name(db, "in2");
    pmap = 0;
    while (psig) {
        pmap2 = mapper_signal_maps(*psig, MAPPER_DIR_INCOMING);
        pmap = mapper_map_query_union(pmap, pmap2);
        psig = mapper_signal_query_next(psig);
    }

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for device 'testdatabase__.2', destination 'in1':\n");

    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    sig = mapper_device_signal_by_name(dev, "in1");
    pmap = mapper_signal_maps(sig, MAPPER_DIR_INCOMING);

    count=0;
    if (!pmap) {
        eprintf("mapper_signal_maps() returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("mapper_signal_maps() returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 2) {
        eprintf("Expected 2 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for source device 'testdatabase__.2', signal 'out1'"
            "\n          AND dest device 'testdatabase.1', signal 'in1':\n");

    // get maps with source signal
    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    sig = mapper_device_signal_by_name(dev, "out1");
    pmap = mapper_signal_maps(sig, MAPPER_DIR_OUTGOING);

    // get maps with destination signal
    dev = mapper_database_device_by_name(db, "testdatabase.1");
    sig = mapper_device_signal_by_name(dev, "in1");
    pmap2 = mapper_signal_maps(sig, MAPPER_DIR_INCOMING);

    // intersect map queries
    pmap = mapper_map_query_intersection(pmap, pmap2);

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 1) {
        eprintf("Expected 1 records, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/

    eprintf("\nFind maps for source device 'testdatabase__.2', signals matching 'out',"
            "\n          AND dest device 'testdatabase.1', all signals:\n");

    // build source query
    dev = mapper_database_device_by_name(db, "testdatabase__.2");
    psig = mapper_device_signals(dev, MAPPER_DIR_ANY);
    psig2 = mapper_database_signals_by_name(db, "*out*");
    psig = mapper_signal_query_intersection(psig, psig2);

    pmap = 0;
    while (psig) {
        pmap2 = mapper_signal_maps(*psig, MAPPER_DIR_OUTGOING);
        pmap = mapper_map_query_union(pmap, pmap2);
        psig = mapper_signal_query_next(psig);
    }

    // build destination query
    dev = mapper_database_device_by_name(db, "testdatabase.1");
    pmap2 = mapper_device_maps(dev, MAPPER_DIR_ANY);

    // intersect queries
    pmap = mapper_map_query_intersection(pmap, pmap2);

    count=0;
    if (!pmap) {
        eprintf("combined query returned 0.\n");
        result = 1;
        goto done;
    }
    if (!*pmap) {
        eprintf("combined query returned something which pointed to 0.\n");
        result = 1;
        goto done;
    }

    while (pmap) {
        count ++;
        printmap(*pmap);
        pmap = mapper_map_query_next(pmap);
    }

    if (count != 1) {
        eprintf("Expected 1 record, but counted %d.\n", count);
        result = 1;
        goto done;
    }

    /*********/
done:
    mapper_network_free(net);
    if (!verbose)
        printf("..................................................");
    printf("Test %s.\n", result ? "FAILED" : "PASSED");
    return result;
}