Пример #1
0
// c'tor: starts app by adding an initial window:
NanoDotApp::NanoDotApp() :
	BApplication("application/x-vnd.eamoon-nanodot-r1"),
	m_pMidiSynth(NULL) {
	
	// initialize synth:
	initSynth();
	
	// get a list of available ports:
	enumeratePorts();

	// add first window:
	addWindow(new NanoDotWindow());
}
Пример #2
0
enum plugin_status plugin_start(const void* parameter)
{
    int retval = 0;

    PLUGIN_IRAM_INIT(rb)

    rb->lcd_setfont(0);

#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
    rb->cpu_boost(true);
#endif

#ifdef RB_PROFILE
    rb->profile_thread();
#endif
    if (initSynth(NULL, ROCKBOX_DIR "/patchset/patchset.cfg",
        ROCKBOX_DIR "/patchset/drums.cfg") == -1)
    {
        printf("\nINIT ERROR\n");
        return -1;
    }
//#ifndef SIMULATOR
    rb->pcm_play_stop();
#if INPUT_SRC_CAPS != 0
    /* Select playback */
    rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
    rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
#endif
    rb->pcm_set_frequency(SAMPLE_RATE); // 44100 22050 11025


    retval = beatboxmain();

#ifdef RB_PROFILE
    rb->profstop();
#endif

    rb->pcm_play_stop();
    rb->pcm_set_frequency(HW_SAMPR_DEFAULT);

#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
    rb->cpu_boost(false);
#endif


    if(retval == -1)
        return PLUGIN_ERROR;
    return PLUGIN_OK;
}
Пример #3
0
static LV2_Handle
instantiate(const LV2_Descriptor*     descriptor,
            double                    rate,
            const char*               bundle_path,
            const LV2_Feature* const* features)
{
  B3S* b3s = (B3S*)malloc(sizeof(B3S));
  if(!b3s) {
    return NULL;
  }
  memset(b3s, 0, sizeof(B3S));

  SampleRateD = rate;

  int i;
  for (i=0; features[i]; ++i) {
    if (!strcmp(features[i]->URI, LV2_URID__map)) {
      b3s->map = (LV2_URID_Map*)features[i]->data;
    } else if (!strcmp(features[i]->URI, LV2_WORKER__schedule)) {
      b3s->schedule = (LV2_Worker_Schedule*)features[i]->data;
    }
  }

  if (!b3s->map || !b3s->schedule) {
    fprintf(stderr, "B3Lv2 error: Host does not support urid:map or work:schedule\n");
    free(b3s);
    return NULL;
  }

  map_setbfree_uris(b3s->map, &b3s->uris);
  lv2_atom_forge_init(&b3s->forge, b3s->map);

  srand ((unsigned int) time (NULL));
  b3s->suspend_ui_msg = 1;
  b3s->boffset = BUFFER_SIZE_SAMPLES;

  b3s->swap_instances = 0;
  b3s->update_gui_now = 0;
  b3s->update_pgm_now = 0;
  b3s->queue_panic = 0;

  b3s->inst = (b_instance*) calloc(1, sizeof(struct b_instance));
  b3s->inst_offline = NULL;

  allocSynth(b3s->inst);

#ifdef JACK_DESCRIPT
  // CODE DUP src/main.c
  char * defaultConfigFile = NULL;
  char * defaultProgrammeFile = NULL;

#ifdef _WIN32
  char wintmp[1024] = "";
  if (ExpandEnvironmentStrings("%localappdata%\\setBfree\\default.cfg", wintmp, 1024)) {
    defaultConfigFile = strdup (wintmp);
  }
  wintmp[0] = '\0';
  if (ExpandEnvironmentStrings("%localappdata%\\setBfree\\default.pgm", wintmp, 1024)) {
    defaultProgrammeFile = strdup (wintmp);
  }
#else // unices: prefer XDG_CONFIG_HOME
  if (getenv("XDG_CONFIG_HOME")) {
    size_t hl = strlen(getenv("XDG_CONFIG_HOME"));
    defaultConfigFile=(char*) malloc(hl+22);
    defaultProgrammeFile=(char*) malloc(hl+22);
    sprintf(defaultConfigFile,    "%s/setBfree/default.cfg", getenv("XDG_CONFIG_HOME"));
    sprintf(defaultProgrammeFile, "%s/setBfree/default.pgm", getenv("XDG_CONFIG_HOME"));
  }
  else if (getenv("HOME")) {
    size_t hl = strlen(getenv("HOME"));
# ifdef __APPLE__
    defaultConfigFile=(char*) malloc(hl+42);
    defaultProgrammeFile=(char*) malloc(hl+42);
    sprintf(defaultConfigFile,    "%s/Library/Preferences/setBfree/default.cfg", getenv("HOME"));
    sprintf(defaultProgrammeFile, "%s/Library/Preferences/setBfree/default.pgm", getenv("HOME"));
# else // linux, BSD, etc
    defaultConfigFile=(char*) malloc(hl+30);
    defaultProgrammeFile=(char*) malloc(hl+30);
    sprintf(defaultConfigFile,    "%s/.config/setBfree/default.cfg", getenv("HOME"));
    sprintf(defaultProgrammeFile, "%s/.config/setBfree/default.pgm", getenv("HOME"));
# endif
  }
#endif

  if (access (defaultConfigFile, R_OK) == 0) {
    parseConfigurationFile (b3s->inst, defaultConfigFile);
  }
#endif

  setControlFunctionCallback(b3s->inst->midicfg, mctl_cb, b3s);
  initSynth(b3s->inst, rate);

#ifdef JACK_DESCRIPT
  if (access (defaultProgrammeFile, R_OK) == 0) {
    loadProgrammeFile (b3s->inst->progs, defaultProgrammeFile);
  }
  free(defaultConfigFile);
  free(defaultProgrammeFile);
#endif

  strcpy(b3s->lv2nfo, "v" VERSION);
  b3s->thirtysec = 0;
#ifdef WITH_SIGNATURE
  {
    b3s->thirtysec = 30 * rate;
    b3s->counter = 0;
    b3s->sin_phase = 0;

    gp3_initialize ();
    load_master_key (); // in header WITH_SIGNATURE
    gp3_loglevel (GP3L_SILENT);
    int rc = -1;
    char signature_file0[1024] = "";
    char signature_file1[1024] = "";
#ifdef _WIN32
	ExpandEnvironmentStrings("%localappdata%\\"SIGFILE, signature_file0, 1024);
	ExpandEnvironmentStrings("%localappdata%\\x42_license.txt", signature_file1, 1024);
#else
	const char * home = getenv("HOME");
	if (home && (strlen(home) + strlen(SIGFILE) + 3) < 1024) {
		sprintf(signature_file0, "%s/.%s", home, SIGFILE);
	}
	if (home && (strlen(home) + 18) < 1024) {
		sprintf(signature_file1, "%s/.x42_license.txt", home);
	}
#endif
	if (!access(signature_file0, R_OK)) {
	  rc = gp3_checksigfile (signature_file0);
	} else if (!access(signature_file1, R_OK)) {
	  rc = gp3_checksigfile (signature_file1);
	}
	if (rc == 0) {
	  bool ok = false;
	  char data[8192];
	  char *tmp=NULL;
	  uint32_t len = gp3_get_text(data, sizeof(data));
	  if (len == sizeof(data)) data[sizeof(data)-1] = '\0';
	  else data[len] = '\0';
	  if ((tmp = strchr(data, '\n'))) *tmp = 0;
	  b3s->lv2nfo[sizeof(b3s->lv2nfo) - 1] = 0;
	  if (tmp++ && *tmp) {
	    if ((tmp = strstr(tmp, SB3_URI))) {
	      char *t1, *t2;
	      ok = true;
	      t1 = tmp + 1 + strlen(SB3_URI);
	      t2 = strchr(t1, '\n');
	      if (t2) { *t2 = 0; }
	      if (strlen(t1) > 0 && strncmp(t1, VERSION, strlen(t1))) {
	      ok = false;
	      }
	    }
	  }
	  if (ok) {
	    b3s->thirtysec = 0;
	    strncat(b3s->lv2nfo, " ", sizeof(b3s->lv2nfo) - strlen(b3s->lv2nfo));
	    strncat(b3s->lv2nfo, data, sizeof(b3s->lv2nfo) - strlen(b3s->lv2nfo));
	  }
	}
	gp3_cleanup ();
  }
#endif
  return (LV2_Handle)b3s;
}
Пример #4
0
/* LV2 -- worker */
static LV2_Worker_Status
work(LV2_Handle                  instance,
     LV2_Worker_Respond_Function respond,
     LV2_Worker_Respond_Handle   handle,
     uint32_t                    size,
     const void*                 data)
{
  B3S* b3s = (B3S*)instance;
  FILE *x;

  if (size != sizeof(struct worknfo)) {
    return LV2_WORKER_ERR_UNKNOWN;
  }
  struct worknfo *w = (struct worknfo*) data;

  switch(w->cmd) {
    case CMD_PURGE:
      if (b3s->inst_offline) {
	// this should not happen
	fprintf(stderr, "B3LV2: re-init in progress\n");
	w->status = -1;
      } else {
	fprintf(stderr, "B3LV2: reinitialize\n");
	b3s->inst_offline = (b_instance*) calloc(1, sizeof(struct b_instance));
	allocSynth(b3s->inst_offline);
	// clone midi map only
	rc_loop_state(b3s->inst->state, clone_map_cb, b3s->inst_offline);
	// copy program info
	memcpy(b3s->inst_offline->progs,  b3s->inst->progs, sizeof(struct b_programme));
	initSynth(b3s->inst_offline, SampleRateD);
	// replay CCs after synth init
	rc_loop_state(b3s->inst->state, clone_cb_mcc, b3s->inst_offline);
	w->status = 0;
      }
      break;
    case CMD_RESET:
      if (b3s->inst_offline) {
	// this should not happen
	fprintf(stderr, "B3LV2: reset ignored. re-init in progress\n");
	w->status = -1;
      } else {
	fprintf(stderr, "B3LV2: factory reset\n");
	b3s->inst_offline = (b_instance*) calloc(1, sizeof(struct b_instance));
	allocSynth(b3s->inst_offline);
	initSynth(b3s->inst_offline, SampleRateD);
	w->status = 0;
      }
      break;
    case CMD_SETCFG:
      if (b3s->inst_offline) {
	// this should not happen
	fprintf(stderr, "B3LV2: setcfg ignored. re-init in progress\n");
	w->status = -1;
      } else {
	// fprintf(stderr, "B3LV2: adding cfg line: %s\n", w->msg);
	b3s->inst_offline = (b_instance*) calloc(1, sizeof(struct b_instance));
	allocSynth(b3s->inst_offline);
	LOCALEGUARD_START;
	// clone current state...
	rc_loop_state(b3s->inst->state, clone_cb_cfg, b3s->inst_offline);
	// copy program info
	memcpy(b3s->inst_offline->progs,  b3s->inst->progs, sizeof(struct b_programme));
	// add user-config
	parseConfigurationLine (b3s->inst_offline, "LV2", 0, w->msg);
	initSynth(b3s->inst_offline, SampleRateD);
	// replay CCs after synth init
	rc_loop_state(b3s->inst->state, clone_cb_mcc, b3s->inst_offline);
	LOCALEGUARD_END;
	w->status = 0;
      }
      break;
    case CMD_LOADPGM:
      fprintf(stderr, "B3LV2: loading pgm file: %s\n", w->msg);
      if (!(w->status=loadProgrammeFile(b3s->inst->progs, w->msg))) {
	b3s->update_pgm_now = 1;
      }
      break;
    case CMD_LOADCFG:
      if (b3s->inst_offline) {
	fprintf(stderr, "B3LV2: restore ignored. re-init in progress\n");
	return LV2_WORKER_ERR_UNKNOWN;
      }
      fprintf(stderr, "B3LV2: loading cfg file: %s\n", w->msg);
      b3s->inst_offline = (b_instance*) calloc(1, sizeof(struct b_instance));
      allocSynth(b3s->inst_offline);

      w->status = parseConfigurationFile (b3s->inst_offline, w->msg);
      initSynth(b3s->inst_offline, SampleRateD);
      break;
    case CMD_SAVECFG:
      create_containing_dir (w->msg);
      x = fopen(w->msg, "w");
      if (x) {
	fprintf(x, "# setBfree config file\n# modificaions on top of default config\n");
	LOCALEGUARD_START;
	rc_loop_state(b3s->inst->state, rcsave_cb, (void*) x);
	LOCALEGUARD_END;
	fclose(x);
	w->status = 0;
      } else {
	w->status = -1;
      }
      break;
    case CMD_SAVEPGM:
      create_containing_dir (w->msg);
      x = fopen(w->msg, "w");
      if (x) {
	fprintf(x, "# setBfree midi program file\n");
	int i;
	for (i=0 ; i < 128; ++i) {
	  int pgmNr = i + b3s->inst->progs->MIDIControllerPgmOffset;
	  if (!(b3s->inst->progs->programmes[pgmNr].flags[0] & FL_INUSE)) {
	    continue;
	  }
	  writeProgramm(pgmNr, &b3s->inst->progs->programmes[pgmNr], "\n    ", x);
	}
	fclose(x);
	w->status = 0;
      } else {
	w->status = -1;
      }
      break;
    case CMD_FREE:
#ifdef DEBUGPRINT
      fprintf(stderr, "free offline instance\n");
#endif
      freeSynth(b3s->inst_offline);
      b3s->inst_offline = NULL;
    break;
  }

  respond(handle, sizeof(struct worknfo), data);
  return LV2_WORKER_SUCCESS;
}
Пример #5
0
static LV2_State_Status
restore(LV2_Handle                  instance,
        LV2_State_Retrieve_Function retrieve,
        LV2_State_Handle            handle,
        uint32_t                    flags,
        const LV2_Feature* const*   features)
{
  B3S* b3s = (B3S*)instance;
  size_t   size;
  uint32_t type;
  uint32_t valflags;
  const void* value = retrieve(handle, b3s->uris.sb3_state, &size, &type, &valflags);

  if (!value) {
    return LV2_STATE_ERR_UNKNOWN;
  }

  if (b3s->inst_offline) {
    fprintf(stderr, "B3LV2: restore ignored. re-init in progress\n");
    return LV2_STATE_ERR_UNKNOWN;
  }

  b3s->inst_offline = (b_instance*) calloc(1, sizeof(struct b_instance));
  allocSynth(b3s->inst_offline);

  const char* cfg = (const char*)value;
  const char *te, *ts = cfg;

  LOCALEGUARD_START;

  /* pass1 - evaulate CFG -- before initializing synth */
  while (ts && *ts && (te=strchr(ts, '\n'))) {
    char *val;
    char kv[1024];
    memcpy(kv, ts, te-ts);
    kv[te-ts]=0;
#ifdef DEBUGPRINT
    fprintf(stderr, "B3LV2 CFG Pass1: %s\n", kv);
#endif
    if(kv[0]=='C' && (val=strchr(kv,'='))) {
      *val=0;
#ifdef DEBUGPRINT
      fprintf(stderr, "B3LV2: evaluateConfigKeyValue(..,\"%s\", \"%s\");\n", kv+2, val+1);
#endif
      evaluateConfigKeyValue((void*)b3s->inst_offline, kv+2, val+1);
    }
    else if(kv[0]=='P') {
#ifdef DEBUGPRINT
      printf("PGM '%s'\n", kv+2);
#endif
      loadProgrammeString(b3s->inst_offline->progs, kv+2);
    }
    ts=te+1;
  }

  initSynth(b3s->inst_offline, SampleRateD);

  /* pass2 - replay CC's after initializing synth */
  ts = cfg;
  while (ts && *ts && (te=strchr(ts, '\n'))) {
    char *val;
    char kv[1024];
    memcpy(kv, ts, te-ts);
    kv[te-ts]=0;
#ifdef DEBUGPRINT
    fprintf(stderr, "B3LV2 CFG Pass2: %s\n", kv);
#endif
    if(kv[0]=='M' && (val=strchr(kv,'='))) {
      *val=0;
#ifdef DEBUGPRINT
      fprintf(stderr, "B3LV2: callMIDIControlFunction(..,\"%s\", %d);\n", kv+2, atoi(val+1));
#endif
      callMIDIControlFunction(b3s->inst_offline->midicfg, kv+2, atoi(val+1));
    }
    ts=te+1;
  }

  LOCALEGUARD_END;

  b3s->swap_instances = 1;
  return LV2_STATE_SUCCESS;
}
Пример #6
0
static int midimain(const void * filename)
{
    int a, notes_used, vol;
    bool is_playing = true;  /* false = paused */

#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
    rb->cpu_boost(true);
#endif
    midi_debug("Loading file");
    mf = loadFile(filename);

    if (mf == NULL)
    {
        midi_debug("Error loading file.");
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
        rb->cpu_boost(false);
#endif
        return -1;
    }

    if (initSynth(mf, ROCKBOX_DIR "/patchset/patchset.cfg",
        ROCKBOX_DIR "/patchset/drums.cfg") == -1)
    {
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
        rb->cpu_boost(false);
#endif
        return -1;
    }

    rb->pcm_play_stop();
#if INPUT_SRC_CAPS != 0
    /* Select playback */
    rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
    rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
#endif
    rb->pcm_set_frequency(SAMPLE_RATE); /* 44100 22050 11025 */

    /*
        * tick() will do one MIDI clock tick. Then, there's a loop here that
        * will generate the right number of samples per MIDI tick. The whole
        * MIDI playback is timed in terms of this value.. there are no forced
        * delays or anything. It just produces enough samples for each tick, and
        * the playback of these samples is what makes the timings right.
        *
        * This seems to work quite well. On a laptop, anyway.
        */

    midi_debug("Okay, starting sequencing");

    bpm = mf->div*1000000/tempo;
    number_of_samples = SAMPLE_RATE/bpm;

    /* Skip over any junk in the beginning of the file, so start playing */
    /* after the first note event */
    do
    {
        notes_used = 0;
        for (a = 0; a < MAX_VOICES; a++)
            if (voices[a].isUsed)
                notes_used++;
        tick();
    } while (notes_used == 0);

#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
    rb->cpu_boost(false);
#endif

    playing_time = 0;
    samples_this_second = 0;

    synthbuf();
    rb->pcm_play_data(&get_more, NULL, NULL, 0);

    while (!quit)
    {
    #ifndef SYNC
        synthbuf();
    #endif
        rb->yield();

        /* Prevent idle poweroff */
        rb->reset_poweroff_timer();

        /* Code taken from Oscilloscope plugin */
        switch (rb->button_get(false))
        {
            case MIDI_VOL_UP:
            case MIDI_VOL_UP | BUTTON_REPEAT:
            {
                vol = rb->global_settings->volume;
                if (vol < rb->sound_max(SOUND_VOLUME))
                {
                    vol++;
                    rb->sound_set(SOUND_VOLUME, vol);
                    rb->global_settings->volume = vol;
                }
                break;
            }

            case MIDI_VOL_DOWN:
            case MIDI_VOL_DOWN | BUTTON_REPEAT:
            {
                vol = rb->global_settings->volume;
                if (vol > rb->sound_min(SOUND_VOLUME))
                {
                    vol--;
                    rb->sound_set(SOUND_VOLUME, vol);
                    rb->global_settings->volume = vol;
                }
                break;
            }

            case MIDI_REWIND:
            {
                /* Rewinding is tricky. Basically start the file over */
                /* but run through the tracks without the synth running */
                rb->pcm_play_stop();
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
                rb->cpu_boost(true);
#endif
                seekBackward(5);
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
                rb->cpu_boost(false);
#endif
                lastswap = !swap;
                synthbuf();
                midi_debug("Rewind to %d:%02d\n", playing_time/60, playing_time%60);
                if (is_playing)
                    rb->pcm_play_data(&get_more, NULL, NULL, 0);
                break;
            }

            case MIDI_FFWD:
            {
                rb->pcm_play_stop();
                seekForward(5);
                lastswap = !swap;
                synthbuf();
                midi_debug("Skip to %d:%02d\n", playing_time/60, playing_time%60);
                if (is_playing)
                    rb->pcm_play_data(&get_more, NULL, NULL, 0);
                break;
            }

            case MIDI_PLAYPAUSE:
            {
                if (is_playing)
                {
                    midi_debug("Paused at %d:%02d\n", playing_time/60, playing_time%60);
                    is_playing = false;
                    rb->pcm_play_stop();
                } else
                {
                    midi_debug("Playing from %d:%02d\n", playing_time/60, playing_time%60);
                    is_playing = true;
                    rb->pcm_play_data(&get_more, NULL, NULL, 0);
                }
                break;
            }

#ifdef MIDI_RC_QUIT
            case MIDI_RC_QUIT:
#endif
            case MIDI_QUIT:
                quit = true;
        }
    }
    return 0;
}
Пример #7
0
int midimain(void * filename)
{

    printf("\nHello.\n");

    rb->splash(HZ/5, true, "LOADING MIDI");

    struct MIDIfile * mf = loadFile(filename);

    rb->splash(HZ/5, true, "LOADING PATCHES");
    if (initSynth(mf, "/.rockbox/patchset/patchset.cfg", "/.rockbox/patchset/drums.cfg") == -1)
    {
        return -1;
    }

/*
 *  This lets you hear the music through the sound card if you are on Simulator
 *  Make a symlink, archos/dsp.raw and make it point to /dev/dsp or whatever
 *  your sound device is.
 */

#if defined(LOCAL_DSP)
    fd=rb->open("/dsp.raw", O_WRONLY);
    int arg, status;
    int bit, samp, ch;

    arg = 16;          /* sample size */
    status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
    status = ioctl(fd, SOUND_PCM_READ_BITS, &arg);
    bit=arg;


    arg = 2;        /* Number of channels, 1=mono */
    status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
    status = ioctl(fd, SOUND_PCM_READ_CHANNELS, &arg);
    ch=arg;

    arg = SAMPLE_RATE; /* Yeah. sampling rate */
    status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
    status = ioctl(fd, SOUND_PCM_READ_RATE, &arg);
    samp=arg;
#else

/* xxx2wav stuff, removed for now, will move to the real way of outputting sound soon */
/*
    file_info_struct file_info;
    file_info.samplerate = SAMPLE_RATE;
    file_info.infile = fd;
    file_info.channels = 2;
    file_info.bitspersample = 16;
    local_init("/miditest.tmp", "/miditest.wav", &file_info, rb);
    fd = file_info.outfile;
*/
#endif


    rb->splash(HZ/5, true, "  I hope this works...  ");




    /*
     * tick() will do one MIDI clock tick. Then, there's a loop here that
     * will generate the right number of samples per MIDI tick. The whole
     * MIDI playback is timed in terms of this value.. there are no forced
     * delays or anything. It just produces enough samples for each tick, and
     * the playback of these samples is what makes the timings right.
     *
     * This seems to work quite well.
     */

    printf("\nOkay, starting sequencing");


    currentSample=0;            /* Sample counting variable */
    outputBufferPosition = 0;


    bpm=mf->div*1000000/tempo;
    numberOfSamples=SAMPLE_RATE/bpm;



    /* Tick() will return 0 if there are no more events left to play */
    while(tick(mf))
    {
        /*
         * Tempo recalculation moved to sequencer.c to be done on a tempo event only
         *
         */
        for(currentSample=0; currentSample<numberOfSamples; currentSample++)
        {

            synthSample(&outputSampleOne, &outputSampleTwo);


            /*
             * 16-bit audio because, well, it's better
             * But really because ALSA's OSS emulation sounds extremely
             * noisy and distorted when in 8-bit mode. I still do not know
             * why this happens.
             */

            outputBuffer[outputBufferPosition]=outputSampleOne&0XFF; // Low byte first
            outputBufferPosition++;
            outputBuffer[outputBufferPosition]=outputSampleOne>>8;   //High byte second
            outputBufferPosition++;

            outputBuffer[outputBufferPosition]=outputSampleTwo&0XFF; // Low byte first
            outputBufferPosition++;
            outputBuffer[outputBufferPosition]=outputSampleTwo>>8;   //High byte second
            outputBufferPosition++;


            /*
             * As soon as we produce 2000 bytes of sound,
             * write it to the sound card. Why 2000? I have
             * no idea. It's 1 AM and I am dead tired.
             */
            if(outputBufferPosition>=2000)
            {
                rb->write(fd, outputBuffer, 2000);
                outputBufferPosition=0;
            }
        }
    }

    printf("\n");

#if !defined(LOCAL_DSP)

/* again, xxx2wav stuff, removed for now */

    /* close_wav(&file_info); */
#else
    rb->close(fd);
#endif
    return 0;
}