Exemple #1
0
static void SampleCallback(GB_gameboy_t *gb, GB_sample_t sample, uint64_t clock)
{
	int l = sample.left - sample_gb.left;
	int r = sample.right - sample_gb.right;
	if (l)
		blip_add_delta(leftblip, clock - sound_start_clock, l);
	if (r)
		blip_add_delta(rightblip, clock - sound_start_clock, r);
	sample_gb = sample;
}
Exemple #2
0
static void SgbSampleCallback(int16_t sl, int16_t sr, uint64_t clock)
{
	int l = sl - sample_sgb.left;
	int r = sr - sample_sgb.right;
	if (l)
		blip_add_delta(leftblip, clock - sound_start_clock, l);
	if (r)
		blip_add_delta(rightblip, clock - sound_start_clock, r);
	sample_sgb.left = sl;
	sample_sgb.right = sr;
}
Exemple #3
0
static inline void square_add_delta(blip_t *blip, uint32_t clocks,
	int32_t *cur_sample, int32_t new_sample)
{
	if ( new_sample != *cur_sample )
	{
		blip_add_delta(blip, clocks, new_sample - *cur_sample);
		*cur_sample = new_sample;
	}
}
Exemple #4
0
void set_audio_signal_level(int16_t level) {
    // TODO: Do something to reduce the initial pop here?
    static int16_t previous_signal_level = 0;

    unsigned time  = frame_offset;
    int      delta = level - previous_signal_level;

    if (is_backwards_frame) {
        // Flip deltas and add them from the end of the frame to reverse audio.
        // Since the exact length of the frame can't be known in advance, the
        // length of each frame is recorded when it is saved to the rewind
        // buffer.
        //
        // This is easiest to visualize by thinking of deltas as fenceposts and
        // the signal level as spans between them. While rewinding, the signal
        // level that's being set should be considered the one to the left of
        // the fencepost.
        //
        // One complication is the boundary between frames while rewinding -
        // there the final sample added to one frame is not followed in time by
        // the first sample of the next frame. To solve this, we bring the
        // signal level down to zero at the end of each frame, and then adjust
        // it to the correct value in the next frame (when rewinding, "to zero"
        // becomes "from zero", and everything still works out). We also call
        // begin_frame() between frames to invalidate the cached signal level
        // in apu.cpp. Together this allows frames to be mixed-and-matched
        // arbitrarily in time.
        //
        // Thanks to Blargg for help on this.
        time  = get_frame_len() - time;
        delta = -delta;
    }
    blip_add_delta(blip, time, delta);

    previous_signal_level = level;
}
Exemple #5
0
int sound_update(unsigned int cycles)
{
    int delta, preamp, time, l, r, *ptr;

    /* Run PSG & FM chips until end of frame */
    SN76489_Update(cycles);
    fm_update(cycles);

    /* FM output pre-amplification */
    preamp = config.fm_preamp;

    /* FM frame initial timestamp */
    time = fm_cycles_start;

    /* Restore last FM outputs from previous frame */
    l = fm_last[0];
    r = fm_last[1];

    /* FM buffer start pointer */
    ptr = fm_buffer;

    /* flush FM samples */
    if (config.hq_fm)
    {
        /* high-quality Band-Limited synthesis */
        do
        {
            /* left channel */
            delta = ((*ptr++ * preamp) / 100) - l;
            l += delta;
            blip_add_delta(snd.blips[0][0], time, delta);

            /* right channel */
            delta = ((*ptr++ * preamp) / 100) - r;
            r += delta;
            blip_add_delta(snd.blips[0][1], time, delta);

            /* increment time counter */
            time += fm_cycles_ratio;
        }
        while (time < cycles);
    }
    else
    {
        /* faster Linear Interpolation */
        do
        {
            /* left channel */
            delta = ((*ptr++ * preamp) / 100) - l;
            l += delta;
            blip_add_delta_fast(snd.blips[0][0], time, delta);

            /* right channel */
            delta = ((*ptr++ * preamp) / 100) - r;
            r += delta;
            blip_add_delta_fast(snd.blips[0][1], time, delta);

            /* increment time counter */
            time += fm_cycles_ratio;
        }
        while (time < cycles);
    }

    /* reset FM buffer pointer */
    fm_ptr = fm_buffer;

    /* save last FM output for next frame */
    fm_last[0] = l;
    fm_last[1] = r;

    /* adjust FM cycle counters for next frame */
    fm_cycles_count = fm_cycles_start = time - cycles;

    /* end of blip buffers time frame */
    blip_end_frame(snd.blips[0][0], cycles);
    blip_end_frame(snd.blips[0][1], cycles);

    /* return number of available samples */
    return blip_samples_avail(snd.blips[0][0]);
}
Exemple #6
0
int psg_context_load(uint8 *state)
{
  int delta[2];
  int i, bufferptr = 0;

  /* initialize delta with current noise channel output */
  if (psg.noiseShiftValue & 1)
  {
    delta[0] = -psg.chanOut[3][0];
    delta[1] = -psg.chanOut[3][1];
  }
  else
  {
    delta[0] = 0;
    delta[1] = 0;
  }

  /* add current tone channels output */
  for (i=0; i<3; i++)
  {
    if (psg.polarity[i] > 0)
    {
      delta[0] -= psg.chanOut[i][0];
      delta[1] -= psg.chanOut[i][1];
    }
  }

  load_param(&psg.clocks,sizeof(psg.clocks));
  load_param(&psg.latch,sizeof(psg.latch));
  load_param(&psg.noiseShiftValue,sizeof(psg.noiseShiftValue));
  load_param(psg.regs,sizeof(psg.regs));
  load_param(psg.freqInc,sizeof(psg.freqInc));
  load_param(psg.freqCounter,sizeof(psg.freqCounter));
  load_param(psg.polarity,sizeof(psg.polarity));
  load_param(psg.chanOut,sizeof(psg.chanOut));

  /* add noise channel output variation */
  if (psg.noiseShiftValue & 1)
  {
    delta[0] += psg.chanOut[3][0];
    delta[1] += psg.chanOut[3][1];
  }

  /* add tone channels output variation */
  for (i=0; i<3; i++)
  {
    if (psg.polarity[i] > 0)
    {
      delta[0] += psg.chanOut[i][0];
      delta[1] += psg.chanOut[i][1];
    }
  }

  /* update mixed channels output */
  if (config.hq_psg)
  {
    blip_add_delta(snd.blips[0], psg.clocks, delta[0], delta[1]);
  }
  else
  {
    blip_add_delta_fast(snd.blips[0], psg.clocks, delta[0], delta[1]);
  }

  return bufferptr;
}