Beispiel #1
0
/**
 * 1) For each node, send Cmd.DISCONNECT command
 * 2) For each node, call node.ctrlItf.close(), node.probeItf.close()
 * 3) call syncItf.close()
 */
int man_platform_disconnect() {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #2
0
int man_platform_tslot_length() {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #3
0
/**
 * Copies the contents of the rtdal.machine structure to the packet
 */
int nod_dispatcher_hwinfo(packet_t *pkt) {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #4
0
int parse_config(char *config_file) {
	config_t config;
	int ret = -1;
	config_setting_t *rtdal,*dac;
	const char *tmp;
	int single_timer;
	int time_slot_us;

	config_init(&config);
	if (!config_read_file(&config, config_file)) {
		aerror_msg("line %d - %s: \n", config_error_line(&config),
				config_error_text(&config));
		goto destroy;
	}

	rtdal = config_lookup(&config, "rtdal");
	if (!rtdal) {
		aerror("Error parsing config file: rtdal section not found.\n");
		goto destroy;
	}

	if (!config_setting_lookup_int(rtdal, "time_slot_us", &time_slot_us)) {
		aerror("time_slot_us field not defined\n");
		goto destroy;
	}

	if (!config_setting_lookup_string(rtdal, "cores", &tmp)) {
		aerror("cores field not defined\n");
		goto destroy;
	}
	nof_cores = parse_cores((char*) tmp);
	if (nof_cores < 0) {
		printf("Error invalid cores %s\n",tmp);
		exit(0);
	}

	if (!config_setting_lookup_bool(rtdal, "enable_usrp", &using_uhd)) {
		aerror("enable_usrp field not defined\n");
		goto destroy;
	}

	if (!config_setting_lookup_bool(rtdal, "timer_mode_single", &single_timer)) {
		aerror("timer_mode_single field not defined\n");
		goto destroy;
	}
	if (using_uhd) {
		if (single_timer) {
			clock_source = SINGLE_TIMER;
		} else {
			clock_source = DAC;
		}
	} else {
		if (single_timer) {
			clock_source = SINGLE_TIMER;
		} else {
			clock_source = MULTI_TIMER;
		}
	}
	if (!config_setting_lookup_string(rtdal, "path_to_libs", &tmp)) {
		aerror("path_to_libs field not defined\n");
		goto destroy;
	}

	strcpy(libs_path,tmp);

	if (using_uhd) {
		dac = config_lookup(&config, "dac");
		if (!dac) {
			aerror("Error parsing config file: dac section not found.\n");
			goto destroy;
		}

#ifdef HAVE_UHD
		double tmp;
		if (!config_setting_lookup_float(dac, "samp_freq", &dac_cfg.inputFreq)) {
			aerror("samp_freq field not defined\n");
			goto destroy;
		}
		dac_cfg.outputFreq = dac_cfg.inputFreq;

		if (!config_setting_lookup_float(dac, "rf_freq", &dac_cfg.inputRFFreq)) {
			aerror("rf_freq field not defined\n");
			goto destroy;
		}
		dac_cfg.outputRFFreq = dac_cfg.inputRFFreq;

		if (!config_setting_lookup_float(dac, "rf_gain", &tmp)) {
			aerror("rf_gain field not defined\n");
			goto destroy;
		}
		dac_cfg.tx_gain = tmp;
		dac_cfg.rx_gain = tmp;

		if (!config_setting_lookup_float(dac, "if_bw", &tmp)) {
			aerror("rf_gain field not defined\n");
			goto destroy;
		}
		dac_cfg.tx_bw = tmp;
		dac_cfg.rx_bw = tmp;

		if (!config_setting_lookup_bool(dac, "sample_is_short", &dac_cfg.sampleType)) {
			aerror("rf_gain field not defined\n");
			goto destroy;
		}

		if (!config_setting_lookup_int(dac, "block_size", &dac_cfg.NsamplesIn)) {
			aerror("block_size field not defined\n");
			goto destroy;
		}
		dac_cfg.NsamplesOut = dac_cfg.NsamplesIn;

		if (!config_setting_lookup_bool(dac, "chain_is_tx", &dac_cfg.chain_is_tx)) {
			aerror("chain_is_tx field not defined\n");
			goto destroy;
		}

		dac_cfg.sampleType = 0;
		dac_cfg.nof_channels = 1;

		uhd_readcfg(&dac_cfg);
#endif
	}
	if (using_uhd) {
#ifdef HAVE_UHD
		timeslot_us = (long int) 1000000*((float) dac_cfg.NsamplesOut/dac_cfg.outputFreq);
#endif
	} else {
		timeslot_us = time_slot_us;
	}
	ret=0;
destroy:
	config_destroy(&config);
	return ret;
}
Beispiel #5
0
int _run_cycle(void* context) {
	int i;
	oesr_context_t *ctx = (oesr_context_t*) context;
	nod_module_t *module = (nod_module_t*) ctx->module;
	nod_waveform_t *waveform = (nod_waveform_t*) module->parent.waveform;
	sdebug("context=0x%x, module_id=%d, changing_status=%d, cur_status=%d waveform_status=%d\n",context,
			module->parent.id, module->changing_status, module->parent.status, waveform->status.cur_status);

	if (waveform->status.cur_status == LOADED && module->parent.status == PARSED) {
		/* ack we have successfully been loaded */
		module->parent.status = LOADED;
		/* register init and stop functions */
		module->init = _call_init;
		module->stop = _call_stop;
	}

	/* Change only if finished previous status change */
	if (!module->changing_status && module->parent.status != waveform->status.cur_status) {
		sdebug("next_tslot=%d, cur_tslot=%d\n",waveform->status.next_timeslot, rtdal_time_slot());
		/* is it time to change? */
		if (rtdal_time_slot() >= waveform->status.next_timeslot) {
			switch(waveform->status.cur_status) {
			case INIT:
			case STOP:
			break;
			case STEP:
				if (module->parent.status == RUN) {
					module->parent.status = waveform->status.cur_status;
				} else {
					module->parent.status = RUN;
				}
				break;
			case PAUSE:
			case RUN:
				/* These status does not need confirmation */
				module->parent.status = waveform->status.cur_status;
			break;
			default:
				break;
			}
		}
	}

	if (!module->changing_status && module->parent.status == RUN) {
#ifdef OESR_API_GETTIME
		/* save start time */
		rtdal_time_get(&module->parent.execinfo.t_exec[1]);
#endif

		/* run aloe cycle */
		for (i=0;i<waveform->tslot_multiplicity;i++) {
			if (Run(context)) {
				sdebug("RUNERROR: module_id=%d\n",module->parent.id);

				/* set run-time error code */
				if (rtdal_process_seterror(module->process,RUNERROR)) {
					aerror("rtdal_process_seterror");
				}
			}
		}
		ctx->tstamp++;

		/* save end time */
#ifdef OESR_API_GETTIME
		rtdal_time_get(&module->parent.execinfo.t_exec[2]);
		rtdal_time_interval(module->parent.execinfo.t_exec);
		nod_module_execinfo_add_sample(&module->parent.execinfo);
		if (DEBUG_TIMEMOD_ID == module->parent.id || DEBUG_TIMEMOD_ID == -1) {
			tmdebug("%d,%d\n",module->parent.id,
				module->parent.execinfo.t_exec[0].tv_usec);
		}
#endif

		/* compute execution time, exponential average, max, etc. and save data to mymodule.execinfo */
#ifdef kk
		/* stat reports */
		for (i=0;i<nof_reporting_vars;i++) {
			module.reporting_variables[i].period_cnt++;
			/* save the first window samples only */
			if (module.reporting_variables[i].period_cnt++<module.reporting_variables[i].window)
				module.reporting_variables[i].serialize(module.reporting_variables[i].report_packet);
			}
			/* send report every period */
			if (module.reporting_variables[i].periodCnt++<module.reporting_variables[i].period) {
				rtdal.newTask(report_variable,&reporting_variables[i]);
			}
		}

		/* write logs */
		for (i=0;i<nof_logs;i++) {
			if (logs[i].w_ptr) {
				rtdal.new_task(oesr_log._writelog,logs[i]);
			}
		}
#endif
	}
Beispiel #6
0
/* Open a device.  If this is a live device, file == NULL. */
static ao_device* _open_device(int driver_id, ao_sample_format *format,
                   ao_option *options, FILE *file)
{
    ao_functions *funcs;
    driver_list *driver;
    ao_device *device=NULL;
    int result;
        ao_sample_format sformat=*format;
        sformat.matrix=NULL;

    /* Get driver id */
    if ( (driver = _get_driver(driver_id)) == NULL ) {
        errno = AO_ENODRIVER;
        goto error;
    }

    funcs = driver->functions;

    /* Check the driver type */
    if (file == NULL &&
        funcs->driver_info()->type != AO_TYPE_LIVE) {

        errno = AO_ENOTLIVE;
        goto error;
    } else if (file != NULL &&
           funcs->driver_info()->type != AO_TYPE_FILE) {

        errno = AO_ENOTFILE;
        goto error;
    }

    /* Make a new device structure */
    if ( (device = _create_device(driver_id, driver,
                      format, file)) == NULL ) {
        errno = AO_EFAIL;
        goto error;
    }

    /* Initialize the device memory; get static channel mapping */
    if (!funcs->device_init(device)) {
        errno = AO_EFAIL;
        goto error;
    }

    /* Load options */
        errno = ao_device_load_options(device,ao_global_options);
        if(errno) goto error;
        errno = ao_device_load_options(device,options);
        if(errno) goto error;

        /* also sanitize the format input channel matrix */
        if(format->matrix){
          sformat.matrix = _sanitize_matrix(format->channels, format->matrix, device);
          if(!sformat.matrix)
            awarn("Input channel matrix invalid; ignoring.\n");

          /* special-case handling of 'M'. */
          if(sformat.channels==1 && sformat.matrix && !strcmp(sformat.matrix,"M")){
            free(sformat.matrix);
            sformat.matrix=NULL;
          }
        }

        /* If device init was able to declare a static channel mapping
           mechanism, reconcile it to the input now.  Odd drivers that
           need to communicate with a backend device to determine
           channel mapping strategy can still bypass this mechanism
           entirely.  Also, drivers like ALSA may need to adjust
           strategy depending on what device is successfully opened,
           etc, but this still saves work later. */

        if(device->output_matrix && sformat.matrix){
          switch(device->output_matrix_order){
          case AO_OUTPUT_MATRIX_FIXED:
            /* Backend channel ordering is immutable and unused
               channels must still be sent.  Look for the highest
               channel number we are able to map from the input
               matrix. */
            {
              unsigned int mask = _matrix_to_channelmask(sformat.channels,sformat.matrix,
                                                         device->output_matrix,
                                                         &device->input_map);
              int max = _channelmask_maxbit(mask);
              if(max<0){
                aerror("Unable to map any channels from input matrix to output");
                errno = AO_EBADFORMAT;
                goto error;
              }
              device->output_channels = max+1;
              device->output_mask = mask;
              device->inter_matrix = _strdup(device->output_matrix);
            }
            break;

          case AO_OUTPUT_MATRIX_COLLAPSIBLE:
            /* the ordering of channels submitted to the backend is
               fixed, but only the channels in use should be present
               in the audio stream */
            {
              unsigned int mask = _matrix_to_channelmask(sformat.channels,sformat.matrix,
                                                         device->output_matrix,
                                                         &device->input_map);
              int channels = _channelmask_bits(mask);
              if(channels<0){
                aerror("Unable to map any channels from input matrix to output");
                errno = AO_EBADFORMAT;
                goto error;
              }
              device->output_channels = channels;
              device->output_mask = mask;
              device->inter_matrix = _channelmask_to_matrix(mask,device->output_matrix);
            }
            break;

          case AO_OUTPUT_MATRIX_PERMUTABLE:
            /* The ordering of channels is freeform.  Only the
               channels in use should be sent, and they may be sent in
               any order.  If possible, leave the input ordering
               unchanged */
            {
              unsigned int mask = _matrix_to_channelmask(sformat.channels,sformat.matrix,
                                                         device->output_matrix,
                                                         &device->input_map);
              int channels = _channelmask_bits(mask);
              if(channels<0){
                aerror("Unable to map any channels from input matrix to output");
                errno = AO_EBADFORMAT;
                goto error;
              }
              device->output_channels = channels;
              device->output_mask = mask;
              device->inter_matrix = _matrix_intersect(sformat.matrix,device->output_matrix);
            }
            break;

          default:
            aerror("Driver backend failed to set output ordering.\n");
            errno = AO_EFAIL;
            goto error;
          }

        }else{
          device->output_channels = sformat.channels;
        }

        /* other housekeeping */
        device->input_channels = sformat.channels;
        device->bytewidth = (sformat.bits+7)>>3;
        device->rate = sformat.rate;

    /* Open the device */
    result = funcs->open(device, &sformat);
    if (!result) {
          errno = AO_EOPENDEVICE;
          goto error;
    }

        /* set up permutation based on finalized inter_matrix mapping */
        /* The only way device->output_channels could be zero here is
           if the driver has opted to ouput no channels (eg, the null
           driver). */
        if(sformat.matrix){
          if(!device->inter_matrix){
            awarn("Driver %s does not support automatic channel mapping;\n"
                 "\tRouting only L/R channels to output.\n\n",
                 info_table[device->driver_id]->short_name);
            device->inter_matrix=_strdup("L,R");
          }
          {

            /* walk thorugh the inter matrix, match channels */
            char *op=device->inter_matrix;
            int count=0;
            device->inter_permute = calloc(device->output_channels,sizeof(int));

            adebug("\n");

            while(count<device->output_channels){
              int m=0,mm;
              char *h=op;

              if(*op){
                /* find mnemonic offset of inter channel */
                while(*h && *h!=',')h++;
                while(mnemonics[m]){
                  if(!strncmp(mnemonics[m],op,h-op))
                    break;
                  m++;
                }
                mm=m;

                /* find match in input if any */
                device->inter_permute[count] = _find_channel(m,sformat.matrix);
                if(device->inter_permute[count] == -1 && sformat.channels == 1){
                  device->inter_permute[count] = _find_channel(1,sformat.matrix);
                  mm=1;
                }
              }else
                device->inter_permute[count] = -1;

              /* display resulting mapping for now */
              if(device->inter_permute[count]>=0){
                adebug("input %d (%s)\t -> backend %d (%s)\n",
                       device->inter_permute[count], mnemonics[mm],
                       count,mnemonics[m]);
              }else{
                adebug("             \t    backend %d (%s)\n",
                       count,mnemonics[m]);
              }
              count++;
              op=h;
              if(*h)op++;
            }
            {
              char **inch = _tokenize_matrix(sformat.matrix);
              int i,j;
              int unflag=0;
              for(j=0;j<sformat.channels;j++){
                for(i=0;i<device->output_channels;i++)
                  if(device->inter_permute[i]==j)break;
                if(i==device->output_channels){
                  adebug("input %d (%s)\t -> none\n",
                         j,inch[j]);
                  unflag=1;
                }
              }
              _free_map(inch);
              if(unflag)
                awarn("Some input channels are unmapped and will not be used.\n");
            }
            averbose("\n");

          }
        }

        /* if there's no actual permutation to do, release the permutation vector */
        if(device->inter_permute && device->output_channels == device->input_channels){
          int i;
          for(i=0;i<device->output_channels;i++)
            if(device->inter_permute[i]!=i)break;
          if(i==device->output_channels){
            free(device->inter_permute);
            device->inter_permute=NULL;
          }
        }

    /* Resolve actual driver byte format */
    device->driver_byte_format =
        _real_byte_format(device->driver_byte_format);

    /* Only create swap buffer if needed */
        if (device->bytewidth>1 &&
            device->client_byte_format != device->driver_byte_format){
          adebug("swap buffer required:\n");
          adebug("  machine endianness: %d\n",ao_is_big_endian());
          adebug("  device->client_byte_format:%d\n",device->client_byte_format);
          adebug("  device->driver_byte_format:%d\n",device->driver_byte_format);
        }

    if ( (device->bytewidth>1 &&
              device->client_byte_format != device->driver_byte_format) ||
             device->inter_permute){

          result = _realloc_swap_buffer(device, DEF_SWAP_BUF_SIZE);

          if (!result) {

            if(sformat.matrix)free(sformat.matrix);
            device->funcs->close(device);
            device->funcs->device_clear(device);
            free(device);
            errno = AO_EFAIL;
            return NULL; /* Couldn't alloc swap buffer */
          }
    }

    /* If we made it this far, everything is OK. */
        if(sformat.matrix)free(sformat.matrix);
    return device;

 error:
        {
          int errtemp = errno;
          if(sformat.matrix)
            free(sformat.matrix);
          ao_close(device);
          errno=errtemp;
        }
        return NULL;
}
Beispiel #7
0
void cmp_rm32_rm32_disp(int dest, int source, int disp)
{
	//eg, "cmp 0xdisp(dest), source"
	//check if a disp8
	if(-127<=(disp*PSIZE) && (disp*PSIZE)<=128) {
		if(isreg(dest)) {
			//destination is a register
			putbyte(0x39);
			if(isreg(source)) {
				//we have a "cmp %eax,%ebx"
				aerror("Error: no mem loc in disp cmp");
			}
			else {
				//we have a "cmp %eax,0xdisp(%ebx)"
				putbyte(0x40+(dest*0x8)+source-0x8);
				putbyte((PSIZE*disp)&0xff);
			}
		}
		else {
			//destination is a memory offset located in register
			putbyte(0x3b);
			if(isreg(source)) {
				//we have a "cmp 0xdisp(%eax),%ebx"
				putbyte(0x40+(source*0x8)+dest-0x8);
				putbyte((PSIZE*disp)&0xff);
			}
			else {
				//we have a "cmp (%eax),(%ebx)"
				//this is an illegal instruction
				aerror("Error: in cmp_rm32_rm32_disp");
			}
		}
	}
	//its a disp32
	else {
		if(isreg(dest)) {
			//destination is a register
			putbyte(0x39);
			if(isreg(source)) {
				//we have a "cmp %eax,%ebx"
				aerror("Error: no mem loc in disp cmp");
			}
			else {
				//we have a "cmp %eax,0xdisp(%ebx)"
				putbyte(0x80+(dest*0x8)+source-0x8);
				put_little_endian(PSIZE*disp);
			}
		}
		else {
			//destination is a memory offset located in register
			putbyte(0x3b);
			if(isreg(source)) {
				//we have a "cmp 0xdisp(%eax),%ebx"
				putbyte(0x80+(source*0x8)+dest-0x8);
				put_little_endian(PSIZE*disp);
			}
			else {
				//we have a "cmp (%eax),(%ebx)"
				//this is an illegal instruction
				aerror("Error: in cmp_rm32_rm32_disp");
			}
		}
	}
}
Beispiel #8
0
int ao_plugin_close(ao_device *device)
{
  ao_macosx_internal *internal = (ao_macosx_internal *) device->internal;
  OSStatus status;
  UInt32 sizeof_running,running;

  // If we never got started and there's data waiting to be played,
  // start now.

  pthread_mutex_lock(&mutex);

  if(internal->output_p){
    internal->output_p=0;
    internal->isStopping = true;

    if(!internal->started && internal->validByteCount){
      status = AudioOutputUnitStart(internal->outputAudioUnit);
      adebug("Starting audio output unit\n");
      if(status){
        pthread_mutex_unlock(&mutex);
        aerror("Failed to start audio output => %d\n",(int)status);
        return 0;
      }
      internal->started = true;
    }

    // For some rare cases (using atexit in your program) Coreaudio tears
    // down the HAL itself, so we do not need to do that here.
    // We wouldn't get an error if we did, but AO would hang waiting for the 
    // AU to flush the buffer
    sizeof_running = sizeof(UInt32);
    AudioUnitGetProperty(internal->outputAudioUnit, 
                         kAudioDevicePropertyDeviceIsRunning,
                         kAudioUnitScope_Input,
                         0,
                         &running, 
                         &sizeof_running);

    if (!running) {
      pthread_mutex_unlock(&mutex);
      return 1;
    }

    // Only stop if we ever got started
    if (internal->started) {

      // Wait for any pending data to get flushed
      while (internal->validByteCount)
        pthread_cond_wait(&cond, &mutex);

      pthread_mutex_unlock(&mutex);
    
      status = AudioOutputUnitStop(internal->outputAudioUnit);
      if (status) {
        awarn("AudioOutputUnitStop returned %d\n", (int)status);
        return 0;
      }

      status = AudioComponentInstanceDispose(internal->outputAudioUnit);
      if (status) {
        awarn("AudioComponentInstanceDispose returned %d\n", (int)status);
        return 0;
      }
    }else
      pthread_mutex_unlock(&mutex);
  }else
    pthread_mutex_unlock(&mutex);

  return 1;
}
Beispiel #9
0
static Lisp_Object Llogcount(Lisp_Object nil, Lisp_Object a)
{
    CSL_IGNORE(nil);
    CSL_IGNORE(a);
    return aerror("logcount");
}
Beispiel #10
0
void mov_rm32_rm32_disp(int dest, int source, int disp)
{
	//eg, "mov 0xdisp(dest), source"
	//check if a disp8
	if(-127<=(disp*PSIZE) && (disp*PSIZE)<=128) {
		if(isreg(dest)) {
			//destination is a register
			putbyte(0x89);
			if(isreg(source)) {
				//we have a "mov %eax,%ebx"
				aerror("Error: no mem loc in disp mov");
			}
			else {
				if(dest==ESP) aerror("Error: ESP in mov_rm32_rm32_disp");
				if(source==ESPM) {
					putbyte(0x44+(dest*0x8));
					putbyte(0x24); //SIB ESP
					putbyte((PSIZE*disp)&0xff);
				}
				else {
					//we have a "mov %eax,0xdisp(%ebx)"
					putbyte(0x40+(dest*0x8)+source-0x8);
					putbyte((PSIZE*disp)&0xff);
				}
			}
		}
		else {
			//destination is a memory offset located in register
			putbyte(0x8b);
			if(isreg(source)) {
				//we have a "mov 0xdisp(%eax),%ebx"
				putbyte(0x40+(source*0x8)+dest-0x8);
				putbyte((PSIZE*disp)&0xff);
			}
			else {
				//we have a "mov (%eax),(%ebx)"
				//this is an illegal instruction
				aerror("Error: in mov_rm32_rm32_disp");
			}
		}
	}
	//its a disp32
	else {
		if(isreg(dest)) {
			//destination is a register
			putbyte(0x89);
			if(isreg(source)) {
				//we have a "mov %eax,%ebx"
				aerror("Error: no mem loc in disp mov");
			}
			else {
				//we have a "mov %eax,0xdisp(%ebx)"
				putbyte(0x80+(dest*0x8)+source-0x8);
				put_little_endian(PSIZE*disp);
			}
		}
		else {
			//destination is a memory offset located in register
			putbyte(0x8b);
			if(isreg(source)) {
				//we have a "mov 0xdisp(%eax),%ebx"
				putbyte(0x80+(source*0x8)+dest-0x8);
				put_little_endian(PSIZE*disp);
			}
			else {
				//we have a "mov (%eax),(%ebx)"
				//this is an illegal instruction
				aerror("Error: in mov_rm32_rm32_disp");
			}
		}
	}
}
Beispiel #11
0
int rtdal_itfspscq_get_blocking(r_itf_t obj) {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #12
0
int rtdal_itfspscq_set_callback(r_itf_t obj, void (*fnc)(void), int prio) {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #13
0
int rtdal_itfspscq_get_delay(r_itf_t obj) {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #14
0
man_platform_model_t* man_platform_get_model() {
	aerror("Not yet implemented");
	return NULL;
}
Beispiel #15
0
/**
 * oesr_itf_status() returns the number of bytes pending in the interface.
 *
 * \param itf Handler returned by the oesr_itf_create() function.
 *
 * \return The number of bytes pending in the interface or -1 on error
 *
 */
int oesr_itf_status(itf_t itf) {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #16
0
int ao_plugin_open(ao_device *device, ao_sample_format *format)
{
  ao_macosx_internal *internal = (ao_macosx_internal *) device->internal;
  OSStatus result = noErr;
  AudioComponent comp;
  AudioComponentDescription desc;
  AudioStreamBasicDescription requestedDesc;
  AURenderCallbackStruct      input;
  UInt32 i_param_size, requestedEndian;

  /* Locate the default output audio unit */
  desc.componentType = kAudioUnitType_Output;
  desc.componentSubType = kAudioUnitSubType_HALOutput;
  desc.componentManufacturer = kAudioUnitManufacturer_Apple;
  desc.componentFlags = 0;
  desc.componentFlagsMask = 0;

  comp = AudioComponentFindNext (NULL, &desc);
  if (comp == NULL) {
    aerror("Failed to start CoreAudio: AudioComponentFindNext returned NULL");
    return 0;
  }

  /* Open & initialize the default output audio unit */
  result = AudioComponentInstanceNew (comp, &internal->outputAudioUnit);
  if (result) {
    aerror("AudioComponentInstanceNew() error => %d\n",(int)result);
    return 0;
  }
  /* Set the desired output device if not default */
  if (internal->outputDevice != kAudioObjectUnknown) {
    result = AudioUnitSetProperty (internal->outputAudioUnit,
                                   kAudioOutputUnitProperty_CurrentDevice,
                                   kAudioUnitScope_Global,
                                   0,
                                   &internal->outputDevice,
                                   sizeof(internal->outputDevice));
    if (result) {
      aerror("AudioComponentSetDevice() error => %d\n",(int)result);
      AudioComponentInstanceDispose(internal->outputAudioUnit);
      return 0;
    }
  }
  internal->output_p=1;

  /* Request desired format of the audio unit.  Let HAL do all
     conversion since it will probably be doing some internal
     conversion anyway. */

  device->driver_byte_format = format->byte_format;
  requestedDesc.mFormatID = kAudioFormatLinearPCM;
  requestedDesc.mFormatFlags = kAudioFormatFlagIsPacked;
  switch(format->byte_format){
  case AO_FMT_BIG:
    requestedDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
    break;
  case AO_FMT_NATIVE:
    if(ao_is_big_endian())
      requestedDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
    break;
  }
  requestedEndian = requestedDesc.mFormatFlags & kAudioFormatFlagIsBigEndian;
  if (format->bits > 8)
    requestedDesc.mFormatFlags |= kAudioFormatFlagIsSignedInteger;

  requestedDesc.mChannelsPerFrame = device->output_channels;
  requestedDesc.mSampleRate = format->rate;
  requestedDesc.mBitsPerChannel = format->bits;
  requestedDesc.mFramesPerPacket = 1;
  requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
  requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket;

  result = AudioUnitSetProperty (internal->outputAudioUnit,
				 kAudioUnitProperty_StreamFormat,
				 kAudioUnitScope_Input,
				 0,
				 &requestedDesc,
				 sizeof(requestedDesc));

  if (result) {
    aerror("AudioUnitSetProperty error => %d\n",(int)result);
    return 0;
  }

  /* what format did we actually get? */
  i_param_size = sizeof(requestedDesc);
  result = AudioUnitGetProperty(internal->outputAudioUnit,
			     kAudioUnitProperty_StreamFormat,
			     kAudioUnitScope_Input,
			     0,
			     &requestedDesc,
			     &i_param_size );
  if (result) {
    aerror("Failed to query modified device hardware settings => %d\n",(int)result);
    return 0;
  }

  /* If any major settings differ, abort */
  if(fabs(requestedDesc.mSampleRate-format->rate) > format->rate*.05){
    aerror("Unable to set output sample rate\n");
    return 0;
  }
  if(requestedDesc.mChannelsPerFrame != device->output_channels){
    aerror("Could not configure %d channel output\n",device->output_channels);
    return 0;
  }
  if(requestedDesc.mBitsPerChannel != format->bits){
    aerror("Could not configure %d bit output\n",format->bits);
    return 0;
  }
  if(requestedDesc.mBitsPerChannel != format->bits){
    aerror("Could not configure %d bit output\n",format->bits);
    return 0;
  }
  if(requestedDesc.mFormatFlags & kAudioFormatFlagIsFloat){
    aerror("Could not configure integer sample output\n");
    return 0;
  }
  if((requestedDesc.mFormatFlags & kAudioFormatFlagsNativeEndian) !=
     requestedEndian){
    aerror("Could not configure output endianness\n");
    return 0;
  }

  if (format->bits > 8){
    if(!(requestedDesc.mFormatFlags & kAudioFormatFlagIsSignedInteger)){
      aerror("Could not configure signed output\n");
      return 0;
    }
  }else{
    if((requestedDesc.mFormatFlags & kAudioFormatFlagIsSignedInteger)){
      aerror("Could not configure unsigned output\n");
      return 0;
    }
  }
  if(requestedDesc.mSampleRate != format->rate){
    awarn("Could not set sample rate to exactly %d; using %g instead.\n",
	  format->rate,(double)requestedDesc.mSampleRate);
  }

  /* set the channel mapping.  MacOSX AUHAL is capable of mapping any
     channel format currently representable in the libao matrix. */

  if(device->output_mask){
    AudioChannelLayout layout;
    memset(&layout,0,sizeof(layout));

    layout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap;
    layout.mChannelBitmap = device->output_mask;

    result = AudioUnitSetProperty(internal->outputAudioUnit,
				  kAudioUnitProperty_AudioChannelLayout,
				  kAudioUnitScope_Input, 0, &layout, sizeof(layout));
    if (result) {
      aerror("Failed to set audio channel layout => %d\n", (int)result);
    }
  }

  /* Set the audio callback */
  input.inputProc = (AURenderCallback) audioCallback;
  input.inputProcRefCon = internal;

  result = AudioUnitSetProperty( internal->outputAudioUnit,
				 kAudioUnitProperty_SetRenderCallback,
				 kAudioUnitScope_Input,
				 0, &input, sizeof( input ));


  if (result) {
    aerror("Callback set error => %d\n",(int)result);
    return 0;
  }

  result = AudioUnitInitialize (internal->outputAudioUnit);
  if (result) {
    aerror("AudioUnitInitialize() error => %d\n",(int)result);
    return 0;
  }

  /* Since we don't know how big to make the buffer until we open the device
     we allocate the buffer here instead of ao_plugin_device_init() */

  internal->bufferByteCount =  (internal->buffer_time * format->rate / 1000) *
    (device->output_channels * format->bits / 8);

  internal->firstValidByteOffset = 0;
  internal->validByteCount = 0;
  internal->buffer = malloc(internal->bufferByteCount);
  memset(internal->buffer, 0, internal->bufferByteCount);
  if (!internal->buffer) {
    aerror("Unable to allocate queue buffer.\n");
    return 0;
  }

  /* limited to stereo for now */
  //if(!device->output_matrix)
  //device->output_matrix=strdup("L,R");

  return 1;
}
Beispiel #17
0
/**
 * Synchronizes with the master clock reference (using shared memory if master is in the same computer
 * or sync interfaces otherwise.
 * @return
 */
int man_platform_sync() {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #18
0
static OSStatus audioCallback (void *inRefCon, 
			       AudioUnitRenderActionFlags *inActionFlags,
			       const AudioTimeStamp *inTimeStamp, 
			       UInt32 inBusNumber, 
			       UInt32 inNumberFrames,
			       AudioBufferList *ioData)
{
  OSStatus err = noErr;
  ao_macosx_internal *internal = (ao_macosx_internal *)inRefCon;
  unsigned int validByteCount;
  unsigned int totalBytesToCopy;
  ao_device *device = internal->device;

  /* Despite the audio buffer list, playback render can only submit a
     single buffer. */

  if(!ioData){
    aerror("Unexpected number of buffers (NULL)\n");
    return 0;
  }

  if(ioData->mNumberBuffers != 1){
    aerror("Unexpected number of buffers (%d)\n",
	   (int)ioData->mNumberBuffers);
    return 0;
  }

  totalBytesToCopy = ioData->mBuffers[0].mDataByteSize;

  pthread_mutex_lock(&mutex);

  validByteCount = internal->validByteCount;

  if (validByteCount < totalBytesToCopy && !internal->isStopping) {
    /* Not enough data ... let it build up a bit more before we start
       copying stuff over. If we are stopping, of course, we should
       just copy whatever we have. This also happens if an application
       pauses output. */
    *inActionFlags = kAudioUnitRenderAction_OutputIsSilence;
    memset(ioData->mBuffers[0].mData, 0, ioData->mBuffers[0].mDataByteSize);
    pthread_mutex_unlock(&mutex);
    return 0;
  }

  {
    unsigned char *outBuffer = ioData->mBuffers[0].mData;
    unsigned int outBufSize = ioData->mBuffers[0].mDataByteSize;
    unsigned int bytesToCopy = MIN(outBufSize, validByteCount);
    unsigned int firstFrag = bytesToCopy;
    unsigned char *sample = internal->buffer + internal->firstValidByteOffset;

    /* Check if we have a wrap around in the ring buffer If yes then
       find out how many bytes we have */
    if (internal->firstValidByteOffset + bytesToCopy > internal->bufferByteCount) 
      firstFrag = internal->bufferByteCount - internal->firstValidByteOffset;

    /* If we have a wraparound first copy the remaining bytes off the end
       and then the rest from the beginning of the ringbuffer */
    if (firstFrag < bytesToCopy) {
      memcpy(outBuffer,sample,firstFrag);
      memcpy(outBuffer+firstFrag,internal->buffer,bytesToCopy-firstFrag);
    } else {
      memcpy(outBuffer,sample,bytesToCopy);
    }
    if(bytesToCopy < outBufSize) /* the stopping case */
      memset(outBuffer+bytesToCopy, 0, outBufSize-bytesToCopy);

    internal->validByteCount -= bytesToCopy;
    internal->firstValidByteOffset = (internal->firstValidByteOffset + bytesToCopy) % 
      internal->bufferByteCount;
  }

  pthread_mutex_unlock(&mutex);
  pthread_cond_signal(&cond);

  return err;
}
Beispiel #19
0
/**
 * Sends a command to a destination. Packet must be filled before.
 */
int man_platform_send_cmd(packet_dest_t dest, packet_command_t cmd) {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #20
0
/* Load a plugin from disk and put the function table into a driver_list
   struct. */
static driver_list *_get_plugin(char *plugin_file)
{
        ao_device *device = ao_global_dummy;
    driver_list *dt;
    void *handle;
        char *prompt="";

    handle = dlopen(plugin_file, DLOPEN_FLAG /* See ao_private.h */);

    if (handle) {
                prompt="calloc() failed";
                dt = (driver_list *)calloc(1,sizeof(driver_list));
        if (!dt) return NULL;

        dt->handle = handle;

        dt->functions = (ao_functions *)calloc(1,sizeof(ao_functions));
        if (!(dt->functions)) {
            free(dt);
            return NULL;
        }

                prompt="ao_plugin_test() missing";
        dt->functions->test = dlsym(dt->handle, "ao_plugin_test");
        if (!(dt->functions->test)) goto failed;

                prompt="ao_plugin_driver_info() missing";
        dt->functions->driver_info =
          dlsym(dt->handle, "ao_plugin_driver_info");
        if (!(dt->functions->driver_info)) goto failed;

                prompt="ao_plugin_device_list() missing";
        dt->functions->device_init =
          dlsym(dt->handle, "ao_plugin_device_init");
        if (!(dt->functions->device_init )) goto failed;

                prompt="ao_plugin_set_option() missing";
        dt->functions->set_option =
          dlsym(dt->handle, "ao_plugin_set_option");
        if (!(dt->functions->set_option)) goto failed;

                prompt="ao_plugin_open() missing";
        dt->functions->open = dlsym(dt->handle, "ao_plugin_open");
        if (!(dt->functions->open)) goto failed;

                prompt="ao_plugin_play() missing";
        dt->functions->play = dlsym(dt->handle, "ao_plugin_play");
        if (!(dt->functions->play)) goto failed;

                prompt="ao_plugin_close() missing";
        dt->functions->close = dlsym(dt->handle, "ao_plugin_close");
        if (!(dt->functions->close)) goto failed;

                prompt="ao_plugin_clear() missing";
        dt->functions->device_clear =
          dlsym(dt->handle, "ao_plugin_device_clear");
        if (!(dt->functions->device_clear)) goto failed;


    } else {
          aerror("Failed to load plugin %s => dlopen() failed\n",plugin_file);
          return NULL;
    }

        adebug("Loaded driver %s\n",dt->functions->driver_info()->short_name);
    return dt;

 failed:
        aerror("Failed to load plugin %s => %s\n",plugin_file,prompt);
    free(dt->functions);
    free(dt);
    return NULL;
}
Beispiel #21
0
/**
 * Processes asynchronous execution error messages from nodes. The format of the asyncError packet is as follows:
 *
 * 1st 32-bit word: Waveform id
 * 2st 32-bit word: Module id
 * 3st 32-bit word: Error code
 * Next: aerrorMsg string
 *
 * For any error message!=OK, set STOP status to the waveform that caused it and print message to SDTDOUT.
 */
int man_platform_process_probe_pkt(void* data, int size) {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #22
0
/**
 * 1) Disconnect all output interfaces
 */
static int nod_dispatcher_disconnect_node() {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #23
0
/**
 * For each node, send a HWINFO command. Save the contents of the received packet into
 * node.hwinfo structure
 */
int man_platform_update() {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #24
0
/**
 * rsh killcf on all nodes
 */
int oesr_man_stop_nodes() {
	aerror("Not yet implemented");
	return -1;
}
Beispiel #25
0
/**
 * Writes the contents of the buffer. Called by runCycle at the end of the timeslot.
 */
static int __attribute__((__unused__)) _write_log(log_t log) {
	aerror("Not yet implemented");
	return -1;
}