コード例 #1
0
ファイル: lv2.c プロジェクト: aelse/setBfree
static void
run(LV2_Handle instance, uint32_t n_samples)
{
  B3S* b3s = (B3S*)instance;
  float* audio[2];

  audio[0] = b3s->outL;
  audio[1] = b3s->outR;

  /* prepare outgoing MIDI */
  const uint32_t capacity = b3s->midiout->atom.size;

  static bool warning_printed = false;
  if (!warning_printed && capacity < 4096) {
    warning_printed = true;
    fprintf(stderr, "B3LV2: LV message buffer is only %d bytes. Expect problems.\n", capacity);
    fprintf(stderr, "B3LV2: if your LV2 host allows one to configure a buffersize use at least 4kBytes.\n");

  }
  lv2_atom_forge_set_buffer(&b3s->forge, (uint8_t*)b3s->midiout, capacity);
  lv2_atom_forge_sequence_head(&b3s->forge, &b3s->frame, 0);

  uint32_t written = 0;

  if (b3s->queue_panic) {
	  b3s->queue_panic = 0;
	  midi_panic(b3s->inst);
  }

  /* Process incoming events from GUI and handle MIDI events */
  if (b3s->midiin) {
    LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(b3s->midiin)->body);
    while(!lv2_atom_sequence_is_end(&(b3s->midiin)->body, (b3s->midiin)->atom.size, ev)) {
      if (ev->body.type == b3s->uris.midi_MidiEvent) {
	/* process midi messages from player */
	if (written + BUFFER_SIZE_SAMPLES < ev->time.frames
	    && ev->time.frames < n_samples) {
	  /* first syntheize sound up until the message timestamp */
	  written = synthSound(b3s, written, ev->time.frames, audio);
	}
	/* send midi message to synth, CC's will trigger hook -> update GUI */
	parse_raw_midi_data(b3s->inst, (uint8_t*)(ev+1), ev->body.size);
      } else if (ev->body.type == b3s->uris.atom_Blank || ev->body.type == b3s->uris.atom_Object) {
	/* process messages from GUI */
	const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
	if (obj->body.otype == b3s->uris.sb3_uiinit) {
	  b3s->update_gui_now = 1;
	} else if (obj->body.otype == b3s->uris.sb3_uimccquery) {
	  midi_loopCCAssignment(b3s->inst->midicfg, 7, mcc_cb, b3s);
	} else if (obj->body.otype == b3s->uris.sb3_uimccset) {
	  const LV2_Atom* cmd = NULL;
	  const LV2_Atom* flags = NULL;
	  lv2_atom_object_get(obj, b3s->uris.sb3_cckey, &flags, b3s->uris.sb3_ccval, &cmd, 0);
	  if (cmd && flags) {
	    midi_uiassign_cc(b3s->inst->midicfg, (const char*)LV2_ATOM_BODY(cmd), ((LV2_Atom_Int*)flags)->body);
	  }
	} else if (obj->body.otype == b3s->uris.sb3_midipgm) {
	  const LV2_Atom* key = NULL;
	  lv2_atom_object_get(obj, b3s->uris.sb3_cckey, &key, 0);
	  if (key) {
	    installProgram(b3s->inst, ((LV2_Atom_Int*)key)->body);
	  }
	} else if (obj->body.otype == b3s->uris.sb3_midisavepgm) {
	  const LV2_Atom* pgm = NULL;
	  const LV2_Atom* name = NULL;
	  lv2_atom_object_get(obj, b3s->uris.sb3_cckey, &pgm, b3s->uris.sb3_ccval, &name, 0);
	  if (pgm && name) {
	    saveProgramm(b3s->inst, (int) ((LV2_Atom_Int*)pgm)->body, (char*) LV2_ATOM_BODY(name), 0);
	    b3s->update_pgm_now = 1;
	  }
	} else if (obj->body.otype == b3s->uris.sb3_loadpgm) {
	  iowork(b3s, obj, CMD_LOADPGM);
	} else if (obj->body.otype == b3s->uris.sb3_loadcfg) {
	  iowork(b3s, obj, CMD_LOADCFG);
	} else if (obj->body.otype == b3s->uris.sb3_savepgm) {
	  iowork(b3s, obj, CMD_SAVEPGM);
	} else if (obj->body.otype == b3s->uris.sb3_savecfg) {
	  iowork(b3s, obj, CMD_SAVECFG);
	} else if (obj->body.otype == b3s->uris.sb3_cfgstr) {
	  if (!b3s->inst_offline) {
	    advanced_config_set(b3s, obj);
	  }
	} else if (obj->body.otype == b3s->uris.sb3_control) {
	  b3s->suspend_ui_msg = 1;
	  const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
	  char *k; int v;
	  if (!get_cc_key_value(&b3s->uris, obj, &k, &v)) {
#ifdef DEBUGPRINT
	    fprintf(stderr, "B3LV2: callMIDIControlFunction(..,\"%s\", %d);\n", k, v);
#endif
	    callMIDIControlFunction(b3s->inst->midicfg, k, v);
	  }
	  b3s->suspend_ui_msg = 0;
	}
      }
      ev = lv2_atom_sequence_next(ev);
    }
  }

  /* synthesize [remaining] sound */
  synthSound(b3s, written, n_samples, audio);

  /* send active keys to GUI - IFF changed */
  bool keychanged = false;
  for (int i = 0 ; i < MAX_KEYS/32; ++i) {
    if (b3s->active_keys[i] != b3s->inst->synth->_activeKeys[i]) {
      keychanged = true;
    }
    b3s->active_keys[i] = b3s->inst->synth->_activeKeys[i];
  }
  if (keychanged) {
    LV2_Atom_Forge_Frame frame;
    lv2_atom_forge_frame_time(&b3s->forge, 0);
    x_forge_object(&b3s->forge, &frame, 1, b3s->uris.sb3_activekeys);
    lv2_atom_forge_property_head(&b3s->forge, b3s->uris.sb3_keyarrary, 0);
    lv2_atom_forge_vector(&b3s->forge, sizeof(unsigned int), b3s->uris.atom_Int, MAX_KEYS/32, b3s->active_keys);
    lv2_atom_forge_pop(&b3s->forge, &frame);
  }

  /* check for new instances */
  postrun(b3s);

  if (b3s->update_gui_now) {
    b3s->update_gui_now = 0;
    b3s->update_pgm_now = 1;
    b3s->suspend_ui_msg = 1;
    rc_loop_state(b3s->inst->state, rc_cb, b3s);
    b3s->suspend_ui_msg = 0;
    forge_kvconfigmessage(&b3s->forge, &b3s->uris, b3s->uris.sb3_cfgkv, "lv2.info", b3s->lv2nfo);
    forge_kvcontrolmessage(&b3s->forge, &b3s->uris, "special.init", (int32_t) b3s->thirtysec);
  } else if (b3s->update_pgm_now) {
    b3s->update_pgm_now = 0;
    loopProgammes(b3s->inst->progs, 1, pgm_cb, b3s);
  }
}
コード例 #2
0
ファイル: main.c プロジェクト: shdawson/setBfree
int jack_audio_callback (jack_nframes_t nframes, void *arg) {
  jack_default_audio_sample_t **out = j_output_bufferptrs;
  int i;

  void *jack_midi_buf = NULL;
  int midi_events = 0;
  jack_nframes_t midi_tme_proc = 0;

  if (!synth_ready) {
    for (i=0;i<AUDIO_CHANNELS;i++) {
      out[i] = (jack_default_audio_sample_t*) jack_port_get_buffer (j_output_port[i], nframes);
      memset(out[i], 0, nframes*sizeof(jack_default_audio_sample_t));
    }
    return (0);
  }

  if (use_jack_midi) {
    jack_midi_buf = jack_port_get_buffer(jack_midi_port, nframes);
    midi_events = jack_midi_get_event_count(jack_midi_buf);
  }

  for (i=0;i<AUDIO_CHANNELS;i++) {
    out[i] = (jack_default_audio_sample_t*) jack_port_get_buffer (j_output_port[i], nframes);
  }

  static int boffset = BUFFER_SIZE_SAMPLES;

  jack_nframes_t written = 0;

  while (written < nframes) {
    int nremain = nframes - written;

    if (boffset >= BUFFER_SIZE_SAMPLES)  {
      if (use_jack_midi) {
	for (i=0; i<midi_events; i++) {
	  jack_midi_event_t ev;
	  jack_midi_event_get(&ev, jack_midi_buf, i);
	  if (ev.time >= written && ev.time < (written + BUFFER_SIZE_SAMPLES))
	    parse_raw_midi_data(arg, ev.buffer, ev.size);
	}
	midi_tme_proc = written + BUFFER_SIZE_SAMPLES;
      }
      boffset = 0;
      oscGenerateFragment (inst.synth, bufA, BUFFER_SIZE_SAMPLES);
      preamp (inst.preamp, bufA, bufB, BUFFER_SIZE_SAMPLES);
      reverb (inst.reverb, bufB, bufC, BUFFER_SIZE_SAMPLES);

#ifdef HAVE_ZITACONVOLVE
      whirlProc2(inst.whirl,
	  bufC,
	  NULL, NULL,
	  bufH[0], bufH[1],
	  bufD[0], bufD[1],
	  BUFFER_SIZE_SAMPLES);

      const float *horn[2] = { bufH[0], bufH[1] };
      const float *drum[2] = { bufD[0], bufD[1] };
      float *out[2] = { bufJ[0], bufJ[1] };

      convolve(horn, out, 2, BUFFER_SIZE_SAMPLES);
      mixdown(out, drum, AUDIO_CHANNELS, BUFFER_SIZE_SAMPLES);
#else
      whirlProc(inst.whirl, bufC, bufJ[0], bufJ[1], BUFFER_SIZE_SAMPLES);
#endif
    }

    int nread = MIN(nremain, (BUFFER_SIZE_SAMPLES - boffset));

    for (i=0;i< AUDIO_CHANNELS; i++) {
      memcpy(&out[i][written], &bufJ[i][boffset], nread*sizeof(float));
    }
    written+=nread;
    boffset+=nread;
  }

  if (use_jack_midi) {
    /* process remaining MIDI events
     * IF nframes < BUFFER_SIZE_SAMPLES OR nframes != N * BUFFER_SIZE_SAMPLES
     */
    for (i=0; i<midi_events; i++) {
      jack_midi_event_t ev;
      jack_midi_event_get(&ev, jack_midi_buf, i);
      if (ev.time >= midi_tme_proc)
	parse_raw_midi_data(arg, ev.buffer, ev.size);
    }
  }

  return(0);
}