CAMLprim value caml_bjack_open(value bit_per_sample, value rate, value name, value server, value input_channels, value output_channels, value _jack_port_flags, value size) { CAMLparam2(name,server); CAMLlocal1(driver); jack_driver_t *drv = JACK_CreateDriver() ; if (drv == NULL) caml_failwith("drv_malloc"); unsigned long r = Unsigned_long_val(rate) ; int jack_ports_flags = Int_val(_jack_port_flags); int errnum = JACK_Open(drv,Int_val(bit_per_sample),&r,String_val(name),String_val(server), Int_val(input_channels),Int_val(output_channels), jack_ports_flags, Int_val(size)); if (errnum != ERR_SUCCESS) caml_bjack_handle_error(errnum) ; driver = caml_alloc_custom(&bjack_drv_ops, sizeof(jack_driver_t*), 1, 0); Bjack_drv_val(driver) = drv; CAMLreturn(driver); }
/* Open the device up */ static int jack_open(int fmt, int sample_rate, int num_channels) { int bits_per_sample; int floating_point = FALSE; int retval; unsigned long rate; TRACE("fmt == %d, sample_rate == %d, num_channels == %d\n", fmt, sample_rate, num_channels); if((fmt == FMT_U8) || (fmt == FMT_S8)) { bits_per_sample = 8; } else if(fmt == FMT_S16_NE) { bits_per_sample = 16; } else if (fmt == FMT_S24_NE) { /* interpreted by bio2jack as 24 bit values packed to 32 bit samples */ bits_per_sample = 24; } else if (fmt == FMT_S32_NE) { bits_per_sample = 32; } else if (fmt == FMT_FLOAT) { bits_per_sample = 32; floating_point = TRUE; } else { TRACE("sample format not supported\n"); return 0; } /* record some useful information */ input.format = fmt; input.frequency = sample_rate; input.bps = bits_per_sample * sample_rate * num_channels; input.channels = num_channels; /* setup the effect as matching the input format */ effect.format = input.format; effect.frequency = input.frequency; effect.channels = input.channels; effect.bps = input.bps; /* if we are already opened then don't open again */ if(output_opened) { /* if something has changed we should close and re-open the connect to jack */ if((output.channels != input.channels) || (output.frequency != input.frequency) || (output.format != input.format)) { TRACE("output.channels is %d, jack_open called with %d channels\n", output.channels, input.channels); TRACE("output.frequency is %ld, jack_open called with %ld\n", output.frequency, input.frequency); TRACE("output.format is %d, jack_open called with %d\n", output.format, input.format); jack_close(); JACK_Close(driver); } else { TRACE("output_opened is TRUE and no options changed, not reopening\n"); paused = FALSE; return 1; } } /* try to open the jack device with the requested rate at first */ output.frequency = input.frequency; output.bps = input.bps; output.channels = input.channels; output.format = input.format; rate = output.frequency; retval = JACK_Open(&driver, bits_per_sample, floating_point, &rate, output.channels); output.frequency = rate; /* avoid compile warning as output.frequency differs in type from what JACK_Open() wants for the type of the rate parameter */ if(retval == ERR_RATE_MISMATCH) { TRACE("set the resampling rate properly"); return 0; } else if(retval != ERR_SUCCESS) { TRACE("failed to open jack with JACK_Open(), error %d\n", retval); return 0; } jack_set_volume(jack_cfg.volume_left, jack_cfg.volume_right); /* sets the volume to stored value */ output_opened = TRUE; paused = FALSE; return 1; }
int audev_init_device(char *devname, long ratewanted, int verbose, extraopt_t *extra) { extraopt_t *opt; int channels; unsigned long rate; int fragsize, format; long jbufframes, jbufsize; int res; if (verbose) { printf("Boodler: JackBIO sound driver.\n"); } if (deviceid) { fprintf(stderr, "Sound device is already open.\n"); return FALSE; } if (!ratewanted) ratewanted = DEFAULT_SOUNDRATE; if (!devname) devname = DEFAULT_CLIENTNAME; rate = ratewanted; channels = 2; fragsize = 32768; format = 0; /* default to little-endian */ for (opt=extra; opt->key; opt++) { if (!strcmp(opt->key, "end") && opt->val) { if (!strcmp(opt->val, "big")) format = 1; else if (!strcmp(opt->val, "little")) format = 0; } else if (!strcmp(opt->key, "connect") && opt->val) { if (!strcmp(opt->val, "none")) connect_mode = CONNECT_NONE; else if (!strcmp(opt->val, "output")) connect_mode = CONNECT_OUTPUT; else if (!strcmp(opt->val, "all")) connect_mode = CONNECT_ALL; else printf("JackB connect parameter must be none, output, or all.\n"); } else if (!strcmp(opt->key, "buffersize") && opt->val) { fragsize = atol(opt->val); } else if (!strcmp(opt->key, "listdevices")) { printf("JackB driver is unable to list devices.\n"); } } JACK_Init(); JACK_SetPortConnectionMode(connect_mode); JACK_SetClientName(devname); res = JACK_Open(&deviceid, 16, &rate, 2); if (res) { fprintf(stderr, "Unable to open JACK connection: error %d\n", res); return FALSE; } jbufsize = JACK_GetBytesFreeSpace(deviceid); jbufframes = jbufsize / JACK_GetBytesPerOutputFrame(deviceid); if (jbufframes/2 >= rate) { sleeptime.tv_sec = 1; sleeptime.tv_usec = 0; } else { sleeptime.tv_sec = 0; sleeptime.tv_usec = (jbufframes/2) * 1000000 / rate; } if (verbose) { printf("Jack client name is \"%s_...\"\n", devname); printf("Sample format is %s-endian.\n", (format ? "big" : "little")); printf("Sample rate is %ld fps.\n", rate); printf("Boodler buffer size is %d.\n", fragsize); printf("Bio2Jack buffer size is %ld (%ld frames).\n", jbufsize, jbufframes); switch (connect_mode) { case CONNECT_NONE: printf("Bio2Jack connect_mode=CONNECT_NONE.\n"); break; case CONNECT_OUTPUT: printf("Bio2Jack connect_mode=CONNECT_OUTPUT.\n"); break; case CONNECT_ALL: printf("Bio2Jack connect_mode=CONNECT_ALL.\n"); break; default: printf("Bio2Jack connect_mode=???.\n"); break; } } sound_rate = rate; sound_channels = channels; sound_format = format; sound_buffersize = fragsize; samplesperbuf = sound_buffersize / 2; framesperbuf = sound_buffersize / (2 * sound_channels); valbuffer = (long *)malloc(sizeof(long) * samplesperbuf); if (!valbuffer) { fprintf(stderr, "Unable to allocate sound buffer.\n"); JACK_Close(deviceid); deviceid = 0; return FALSE; } rawbuffer = (char *)malloc(sound_buffersize); if (!rawbuffer) { fprintf(stderr, "Unable to allocate sound buffer.\n"); free(valbuffer); JACK_Close(deviceid); deviceid = 0; return FALSE; } return TRUE; }