Example #1
0
int device_start_sn764xx(UINT8 ChipID, int clock, int shiftregwidth, int noisetaps,
						 int negate, int stereo, int clockdivider, int freq0)
{
	sn764xx_state *info;
	int rate;
	
	if (ChipID >= MAX_CHIPS)
		return 0;
	
	info = &SN764xxData[ChipID];
	/* emulator create */
	switch(EMU_CORE)
	{
	case EC_MAME:
		rate = sn76496_start(&info->chip, clock, shiftregwidth, noisetaps,
							negate, stereo, clockdivider, freq0);
		sn76496_freq_limiter(clock & 0x3FFFFFFF, clockdivider, SampleRate);
		break;
#ifdef ENABLE_ALL_CORES
	case EC_MAXIM:
		rate = SampleRate;
		info->chip = SN76489_Init(clock, rate);
		if (info->chip == NULL)
			return 0;
		SN76489_Config((SN76489_Context*)info->chip, noisetaps, shiftregwidth, 0);
		break;
#endif
	}
 
	return rate;
}
Example #2
0
int device_start_sn764xx(void **_info, int EMU_CORE, int clock, int SampleRate, int shiftregwidth, int noisetaps,
						 int negate, int stereo, int clockdivider, int freq0)
{
	sn764xx_state *info;
	int rate;

#ifdef ENABLE_ALL_CORES
	if (EMU_CORE >= 0x02)
		EMU_CORE = EC_MAME;
#else
	EMU_CORE = EC_MAME;
#endif
	
	info = (sn764xx_state*) calloc(1, sizeof(sn764xx_state));
	*_info = (void *) info;
	/* emulator create */
	info->EMU_CORE = EMU_CORE;
	switch(EMU_CORE)
	{
	case EC_MAME:
		rate = sn76496_start(&info->chip, clock, shiftregwidth, noisetaps,
							negate, stereo, clockdivider, freq0);
		sn76496_freq_limiter(clock & 0x3FFFFFFF, clockdivider, SampleRate);
		break;
#ifdef ENABLE_ALL_CORES
	case EC_MAXIM:
		rate = SampleRate;
		info->chip = SN76489_Init(clock, rate);
		if (info->chip == NULL)
			return 0;
		SN76489_Config((SN76489_Context*)info->chip, noisetaps, shiftregwidth, 0);
		break;
#endif
	}

	return rate;
}
Example #3
0
/* Initialize sound chips emulation */
void sound_init(void)
{
    /* Number of M-cycles executed per second.                                              */
    /*                                                                                      */
    /* All emulated chips are kept in sync by using a common oscillator (MCLOCK)            */
    /*                                                                                      */
    /* The original console would run exactly 53693175 M-cycles (53203424 for PAL), with    */
    /* 3420 M-cycles per line and 262 (313 for PAL) lines per frame, which gives an exact   */
    /* framerate of 59.92 (49.70 for PAL) fps.                                              */
    /*                                                                                      */
    /* Since audio samples are generated at the end of the frame, to prevent audio skipping */
    /* or lag between emulated frames, number of samples rendered per frame must be set to  */
    /* output samplerate (number of samples played per second) divided by output framerate  */
    /* (number of frames emulated per seconds).                                             */
    /*                                                                                      */
    /* On some systems, we may want to achieve 100% smooth video rendering by synchronizing */
    /* frame emulation with VSYNC, which frequency is generally not exactly those values.   */
    /* In that case, number of frames emulated per seconds is the same as the number of     */
    /* frames rendered per seconds by the host system video hardware.                       */
    /*                                                                                      */
    /* When no framerate is specified, base clock is original master clock value.           */
    /* Otherwise, it is based on the output framerate.                                      */
    /*                                                                                      */
    double mclk = snd.frame_rate ? (MCYCLES_PER_LINE * lines_per_frame * snd.frame_rate) : system_clock;

    /* For maximal accuracy, sound chips run in synchronization with 68k and Z80 cpus       */
    /* These values give the exact number of M-cycles executed per internal sample clock:   */
    /* . PSG chip runs at original rate and audio is resampled internally after each update */
    /* . FM chips run by default (if HQ mode disabled) at the output rate directly          */
    /* We use 21.11 fixed point precision (max. mcycle value is 3420*313 i.e 21 bits max)   */
    psg_cycles_ratio  = 16 * 15 * (1 << 11);
    fm_cycles_ratio   = (unsigned int)(mclk / (double) snd.sample_rate * 2048.0);
    psg_cycles_count  = 0;
    fm_cycles_count   = 0;

    /* Initialize PSG core (input clock should be based on emulated system clock) */
    SN76489_Init(mclk/15.0,snd.sample_rate);

    /* Initialize FM cores (input clock and samplerate are only used when HQ mode is disabled) */
    if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
    {
        /* YM2612 */
        YM2612Init(mclk/7.0,snd.sample_rate);
        YM_Reset = YM2612ResetChip;
        YM_Update = YM2612Update;
        YM_Write = YM2612Write;

        /* In HQ mode, YM2612 is running at original rate (one sample each 144*7 M-cycles) */
        /* Audio is resampled externally at the end of a frame. */
        if (config.hq_fm)
        {
            fm_cycles_ratio = 144 * 7 * (1 << 11);
            Fir_Resampler_time_ratio(mclk / (double)snd.sample_rate / (144.0 * 7.0), config.rolloff);
        }
    }
    else
    {
        /* YM2413 */
        YM2413Init(mclk/15.0,snd.sample_rate);
        YM_Reset = YM2413ResetChip;
        YM_Update = YM2413Update;
        YM_Write = YM2413Write;

        /* In HQ mode, YM2413 is running at original rate (one sample each 72*15 M-cycles)  */
        /* Audio is resampled externally at the end of a frame. */
        if (config.hq_fm)
        {
            fm_cycles_ratio = 72 * 15 * (1 << 11);
            Fir_Resampler_time_ratio(mclk / (double)snd.sample_rate / (72.0 * 15.0), config.rolloff);
        }
    }

#ifdef LOGSOUND
    error("%f mcycles per second\n", mclk);
    error("%d mcycles per PSG sample\n", psg_cycles_ratio);
    error("%d mcycles per FM sample\n", fm_cycles_ratio);
#endif
}
Example #4
0
int sound_init(void)
{
    uint8 *buf = NULL;
    int restore_fm = 0;
    int i;

    /* Save register settings */
    if(snd.enabled && sms.use_fm)
    {
        restore_fm = 1;
        buf = malloc(FM_GetContextSize());
        FM_GetContext(buf);
    }

    /* If we are reinitializing, shut down sound emulation */
    if(snd.enabled)
    {
        sound_shutdown();
    }

    /* Disable sound until initialization is complete */
    snd.enabled = 0;

    /* Check if sample rate is invalid */
    if(snd.sample_rate < 8000 || snd.sample_rate > 48000)
        return 0;

    /* Assign stream mixing callback if none provided */
    if(!snd.mixer_callback)
        snd.mixer_callback = sound_mixer_callback;

    /* Calculate number of samples generated per frame */
#ifdef PSP
    /* PSP version requires a sample count divisible by 64 */
    snd.sample_count = ((snd.sample_rate / snd.fps) + 63) & ~63;
#else
    snd.sample_count = (snd.sample_rate / snd.fps);
#endif

    /* Calculate size of sample buffer */
    snd.buffer_size = snd.sample_count * 2;

    /* Free sample buffer position table if previously allocated */
    if(smptab)
    {
        free(smptab);
        smptab = NULL;
    }

	/* Prepare incremental info */
    snd.done_so_far = 0;
    smptab_len = (sms.display == DISPLAY_NTSC) ? 262 : 313;
    smptab = malloc(smptab_len * sizeof(int));
    if(!smptab) return 0;
    for (i = 0; i < smptab_len; i++)
    {
    	double calc = (snd.sample_count * i);
        calc = calc / (double)smptab_len;
    	smptab[i] = (int)calc;
    }

    /* Allocate emulated sound streams */
    for(i = 0; i < STREAM_MAX; i++)
    {
        snd.stream[i] = malloc(snd.buffer_size);
        if(!snd.stream[i]) return 0;
        memset(snd.stream[i], 0, snd.buffer_size);
    }

    /* Allocate sound output streams */
    snd.output[0] = calloc(snd.sample_count, sizeof(int16));
    snd.output[1] = calloc(snd.sample_count, sizeof(int16));
    if(!snd.output[0] || !snd.output[1]) return 0;

    /* Set up buffer pointers */
    fm_buffer = (int16 **)&snd.stream[STREAM_FM_MO];
    psg_buffer = (int16 **)&snd.stream[STREAM_PSG_L];

    /* Set up SN76489 emulation */
    SN76489_Init(0, snd.psg_clock, snd.sample_rate);

    /* Set up YM2413 emulation */
    FM_Init();

    /* Inform other functions that we can use sound */
    snd.enabled = 1;

    /* Restore YM2413 register settings */
    if(restore_fm)
    {
        FM_SetContext(buf);
    }

    return 1;
}
Example #5
0
int audio_init(int samplerate, double framerate)
{
  /* Number of M-cycles executed per second. */
  /* All emulated chips are kept in sync by using a common oscillator (MCLOCK)            */
  /*                                                                                      */
  /* The original console would run exactly 53693175 M-cycles per sec (53203424 for PAL), */
  /* 3420 M-cycles per line and 262 (313 for PAL) lines per frame, which gives an exact   */
  /* framerate of 59.92 (49.70 for PAL) frames per second.                                */
  /*                                                                                      */
  /* Since audio samples are generated at the end of the frame, to prevent audio skipping */
  /* or lag between emulated frames, number of samples rendered per frame must be set to  */
  /* output samplerate (number of samples played per second) divided by input framerate   */
  /* (number of frames emulated per seconds).                                             */
  /*                                                                                      */
  /* On some systems, we may want to achieve 100% smooth video rendering by synchronizing */
  /* frame emulation with VSYNC, which frequency is generally not exactly those values.   */
  /* In that case, input framerate (number of frames emulated per seconds) is the same as */
  /* output framerate (number of frames rendered per seconds) by the host video hardware. */
  /*                                                                                      */
  /* When no framerate is specified, base clock is set to original master clock value.    */
  /* Otherwise, it is set to number of M-cycles emulated per line (fixed) multiplied by   */
  /* number of lines per frame (VDP mode specific) multiplied by input framerate.         */
  /*                                                                                      */
  double mclk = framerate ? (MCYCLES_PER_LINE * (vdp_pal ? 313 : 262) * framerate) : system_clock;

  /* Shutdown first */
  audio_shutdown();

  /* Clear the sound data context */
  memset(&snd, 0, sizeof (snd));

  /* Initialize audio rates */
  snd.sample_rate = samplerate;
  snd.frame_rate  = framerate;

  /* Initialize Blip Buffers */
  snd.blips[0][0] = blip_new(samplerate / 10);
  snd.blips[0][1] = blip_new(samplerate / 10);
  if (!snd.blips[0][0] || !snd.blips[0][1])
  {
    audio_shutdown();
    return -1;
  }

  /* For maximal accuracy, sound chips are running at their original rate using common */
  /* master clock timebase so they remain perfectly synchronized together, while still */
  /* being synchronized with 68K and Z80 CPUs as well. Mixed sound chip output is then */
  /* resampled to desired rate at the end of each frame, using Blip Buffer.            */
  blip_set_rates(snd.blips[0][0], mclk, samplerate);
  blip_set_rates(snd.blips[0][1], mclk, samplerate);

  /* Initialize PSG core */
  SN76489_Init(snd.blips[0][0], snd.blips[0][1], (system_hw < SYSTEM_MARKIII) ? SN_DISCRETE : SN_INTEGRATED);

  /* Mega CD sound hardware */
  if (system_hw == SYSTEM_MCD)
  {
    /* allocate blip buffers */
    snd.blips[1][0] = blip_new(samplerate / 10);
    snd.blips[1][1] = blip_new(samplerate / 10);
    snd.blips[2][0] = blip_new(samplerate / 10);
    snd.blips[2][1] = blip_new(samplerate / 10);
    if (!snd.blips[1][0] || !snd.blips[1][1] || !snd.blips[2][0] || !snd.blips[2][1])
    {
      audio_shutdown();
      return -1;
    }

    /* Initialize PCM core */
    pcm_init(snd.blips[1][0], snd.blips[1][1]);

    /* Initialize CDD core */
    cdd_init(snd.blips[2][0], snd.blips[2][1]);
  }

  /* Set audio enable flag */
  snd.enabled = 1;

  /* Reset audio */
  audio_reset();

  return (0);
}