Example #1
0
void pcm_init(double clock, int samplerate)
{
  /* PCM chip is running at original rate and is synchronized with SUB-CPU  */
  /* Chip output is resampled to desired rate using Blip Buffer. */
  blip_set_rates(snd.blips[1][0], clock / PCM_SCYCLES_RATIO, samplerate);
  blip_set_rates(snd.blips[1][1], clock / PCM_SCYCLES_RATIO, samplerate);
}
Example #2
0
void pcm_init(blip_t* left, blip_t* right)
{
  /* number of SCD master clocks run per second */
  double mclk = snd.frame_rate ? (SCYCLES_PER_LINE * (vdp_pal ? 313 : 262) * snd.frame_rate) : SCD_CLOCK;

  /* PCM chips is running at original rate and is synchronized with SUB-CPU  */
  /* Chip output is resampled to desired rate using Blip Buffer. */
  blip[0] = left;
  blip[1] = right;
  blip_set_rates(left, mclk / PCM_SCYCLES_RATIO, snd.sample_rate);
  blip_set_rates(right, mclk / PCM_SCYCLES_RATIO, snd.sample_rate);
}
Example #3
0
void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAudioStyle style) {
	audio->samples = samples;
	audio->left = blip_new(BLIP_BUFFER_SIZE);
	audio->right = blip_new(BLIP_BUFFER_SIZE);
	audio->clockRate = DMG_LR35902_FREQUENCY;
	// Guess too large; we hang producing extra samples if we guess too low
	blip_set_rates(audio->left, DMG_LR35902_FREQUENCY, 96000);
	blip_set_rates(audio->right, DMG_LR35902_FREQUENCY, 96000);
	audio->forceDisableCh[0] = false;
	audio->forceDisableCh[1] = false;
	audio->forceDisableCh[2] = false;
	audio->forceDisableCh[3] = false;
	audio->masterVolume = GB_AUDIO_VOLUME_MAX;
	audio->nr52 = nr52;
	audio->style = style;
}
Example #4
0
static void _mSDLAudioCallback(void* context, Uint8* data, int len) {
	struct mSDLAudio* audioContext = context;
	if (!context || !audioContext->core) {
		memset(data, 0, len);
		return;
	}
	blip_t* left = NULL;
	blip_t* right = NULL;
	int32_t clockRate = GBA_ARM7TDMI_FREQUENCY;
	if (audioContext->core) {
		left = audioContext->core->getAudioChannel(audioContext->core, 0);
		right = audioContext->core->getAudioChannel(audioContext->core, 1);
		clockRate = audioContext->core->frequency(audioContext->core);
	}
	double fauxClock = 1;
	if (audioContext->sync) {
		if (audioContext->sync->fpsTarget > 0) {
			fauxClock = GBAAudioCalculateRatio(1, audioContext->sync->fpsTarget, 1);
		}
		mCoreSyncLockAudio(audioContext->sync);
	}
	blip_set_rates(left, clockRate, audioContext->obtainedSpec.freq * fauxClock);
	blip_set_rates(right, clockRate, audioContext->obtainedSpec.freq * fauxClock);
	len /= 2 * audioContext->obtainedSpec.channels;
	int available = blip_samples_avail(left);
	if (available > len) {
		available = len;
	}
	blip_read_samples(left, (short*) data, available, audioContext->obtainedSpec.channels == 2);
	if (audioContext->obtainedSpec.channels == 2) {
		blip_read_samples(right, ((short*) data) + 1, available, 1);
	}

	if (audioContext->sync) {
		mCoreSyncConsumeAudio(audioContext->sync);
	}
	if (available < len) {
		memset(((short*) data) + audioContext->obtainedSpec.channels * available, 0, (len - available) * audioContext->obtainedSpec.channels * sizeof(short));
	}
}
Example #5
0
ECL_EXPORT bool Init(bool cgb, const uint8_t *spc, int spclen)
{
	if (spc)
	{
		GB_init_sgb(&GB);
		if (!sgb_init(spc, spclen))
			return false;
		sgb = true;
	}
	else if (cgb)
	{
		GB_init_cgb(&GB);
	}
	else
	{
		GB_init(&GB);
	}

	if (GB_load_boot_rom(&GB, "boot.rom") != 0)
		return false;
	if (GB_load_rom(&GB, "game.rom") != 0)
		return false;

	GB_set_pixels_output(&GB, GBPixels);
	GB_set_vblank_callback(&GB, VBlankCallback);
	GB_set_log_callback(&GB, LogCallback);
	GB_set_rgb_encode_callback(&GB, RgbEncodeCallback);
	GB_set_infrared_callback(&GB, InfraredCallback);
	GB_set_rumble_callback(&GB, RumbleCallback);
	GB_set_sample_callback(&GB, SampleCallback);

	leftblip = blip_new(1024);
	rightblip = blip_new(1024);
	blip_set_rates(leftblip, sgb ? SOUND_RATE_SGB : SOUND_RATE_GB, 44100);
	blip_set_rates(rightblip, sgb ? SOUND_RATE_SGB : SOUND_RATE_GB, 44100);

	return true;
}
Example #6
0
void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
	audio->samples = samples;
#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
	CircleBufferInit(&audio->left, samples * sizeof(int16_t));
	CircleBufferInit(&audio->right, samples * sizeof(int16_t));
#else
	audio->left = blip_new(BLIP_BUFFER_SIZE);
	audio->right = blip_new(BLIP_BUFFER_SIZE);
	// Guess too large; we hang producing extra samples if we guess too low
	blip_set_rates(audio->left,  GBA_ARM7TDMI_FREQUENCY, 96000);
	blip_set_rates(audio->right, GBA_ARM7TDMI_FREQUENCY, 96000);
#endif
	CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
	CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);

	audio->forceDisableCh[0] = false;
	audio->forceDisableCh[1] = false;
	audio->forceDisableCh[2] = false;
	audio->forceDisableCh[3] = false;
	audio->forceDisableChA = false;
	audio->forceDisableChB = false;
	audio->masterVolume = GBA_AUDIO_VOLUME_MAX;
}
Example #7
0
void end_audio_frame() {
    if (frame_offset == 0)
        // No audio added; blip_end_frame() dislikes being called with an
        // offset of 0
        return;

    assert(!(is_backwards_frame && frame_offset != get_frame_len()));

    // Bring the signal level at the end of the frame to zero as outlined in
    // set_audio_signal_level()
    set_audio_signal_level(0);

    blip_end_frame(blip, frame_offset);

    if (playback_started) {
        // Fudge playback rate by an amount proportional to the difference
        // between the desired and current buffer fill levels to try to steer
        // towards it

        double const fudge_factor = 1.0 + 2*max_adjust*(0.5 - fill_level());
        blip_set_rates(blip, cpu_clock_rate, sample_rate*fudge_factor);
    }
    else {
        if (fill_level() >= 0.5) {
            start_audio_playback();
            playback_started = true;
        }
    }

    int const n_samples = blip_read_samples(blip, blip_samples, ARRAY_LEN(blip_samples), 0);
    // We expect to read all samples from blip_buf. If something goes wrong and
    // we don't, clear the buffer to prevent data piling up in blip_buf's
    // buffer (which lacks bounds checking).
    int const avail = blip_samples_avail(blip);
    if (avail != 0) {
        printf("Warning: didn't read all samples from blip_buf (%d samples remain) - dropping samples\n",
          avail);
        blip_clear(blip);
    }

#ifdef RECORD_MOVIE
    add_movie_audio_frame(blip_samples, n_samples);
#endif

    // Save the samples to the audio ring buffer

    lock_audio();
    write_samples(blip_samples, n_samples);
    unlock_audio();
}
Example #8
0
static void _GBASDLAudioCallback(void* context, Uint8* data, int len) {
	struct GBASDLAudio* audioContext = context;
	if (!context || !audioContext->thread || !audioContext->thread->gba) {
		memset(data, 0, len);
		return;
	}
#if RESAMPLE_LIBRARY == RESAMPLE_NN
	audioContext->ratio = GBAAudioCalculateRatio(audioContext->thread->gba->audio.sampleRate, audioContext->thread->fpsTarget, audioContext->obtainedSpec.freq);
	if (audioContext->ratio == INFINITY) {
		memset(data, 0, len);
		return;
	}
	struct GBAStereoSample* ssamples = (struct GBAStereoSample*) data;
	len /= 2 * audioContext->obtainedSpec.channels;
	if (audioContext->obtainedSpec.channels == 2) {
		GBAAudioResampleNN(&audioContext->thread->gba->audio, audioContext->ratio, &audioContext->drift, ssamples, len);
	}
#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
	double fauxClock = GBAAudioCalculateRatio(1, audioContext->thread->fpsTarget, 1);
	GBASyncLockAudio(&audioContext->thread->sync);
	blip_set_rates(audioContext->thread->gba->audio.left, GBA_ARM7TDMI_FREQUENCY, audioContext->obtainedSpec.freq * fauxClock);
	blip_set_rates(audioContext->thread->gba->audio.right, GBA_ARM7TDMI_FREQUENCY, audioContext->obtainedSpec.freq * fauxClock);
	len /= 2 * audioContext->obtainedSpec.channels;
	int available = blip_samples_avail(audioContext->thread->gba->audio.left);
	if (available > len) {
		available = len;
	}
	blip_read_samples(audioContext->thread->gba->audio.left, (short*) data, available, audioContext->obtainedSpec.channels == 2);
	if (audioContext->obtainedSpec.channels == 2) {
		blip_read_samples(audioContext->thread->gba->audio.right, ((short*) data) + 1, available, 1);
	}
	GBASyncConsumeAudio(&audioContext->thread->sync);
	if (available < len) {
		memset(((short*) data) + audioContext->obtainedSpec.channels * available, 0, (len - available) * audioContext->obtainedSpec.channels * sizeof(short));
	}
#endif
}
Example #9
0
void audio_set_rate(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;

  /* 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], mclk, samplerate);

  /* Mega CD sound hardware */
  if (system_hw == SYSTEM_MCD)
  {
    /* number of SCD master clocks run per second */
    mclk = (mclk / system_clock) * SCD_CLOCK;

    /* PCM core */
    pcm_init(mclk, samplerate);

    /* CDD core */
    cdd_init(samplerate);
  }

  /* Reinitialize internal rates */
  snd.sample_rate = samplerate;
  snd.frame_rate  = framerate;
}
Example #10
0
bool retro_load_game(const struct retro_game_info* game) {
	struct VFile* rom;
	if (game->data) {
		data = anonymousMemoryMap(game->size);
		dataSize = game->size;
		memcpy(data, game->data, game->size);
		rom = VFileFromMemory(data, game->size);
	} else {
		data = 0;
		rom = VFileOpen(game->path, O_RDONLY);
	}
	if (!rom) {
		return false;
	}

	core = NULL;
#ifdef M_CORE_GBA
	if (!core && GBAIsROM(rom)) {
		core = GBACoreCreate();
	}
#endif
#ifdef M_CORE_GB
	if (!core && GBIsROM(rom)) {
		core = GBCoreCreate();
	}
#endif
	if (!core) {
		rom->close(rom);
		mappedMemoryFree(data, game->size);
		return false;
	}
	mCoreInitConfig(core, NULL);
	core->init(core);
	core->setAVStream(core, &stream);

	outputBuffer = malloc(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
	core->setVideoBuffer(core, outputBuffer, 256);

	core->setAudioBufferSize(core, SAMPLES);

	blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768);
	blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768);

	core->setRumble(core, &rumble);

#ifdef M_CORE_GBA
	if (core->platform(core) == PLATFORM_GBA) {
		struct GBA* gba = core->board;
		gba->luminanceSource = &lux;

		const char* sysDir = 0;
		if (environCallback(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysDir)) {
			char biosPath[PATH_MAX];
			snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, "gba_bios.bin");
			struct VFile* bios = VFileOpen(biosPath, O_RDONLY);
			if (bios) {
				core->loadBIOS(core, bios, 0);
			}
		}

		GBACheatDeviceCreate(&cheats);
		GBACheatAttachDevice(gba, &cheats);
		GBACheatSetInit(&cheatSet, "libretro");
		GBACheatAddSet(&cheats, &cheatSet);
	}
#endif

	savedata = anonymousMemoryMap(SIZE_CART_FLASH1M);
	struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M);

	_reloadSettings();
	core->loadROM(core, rom);
	core->loadSave(core, save);
	core->reset(core);
	return true;
}
Example #11
0
bool retro_load_game(const struct retro_game_info* game) {
	struct VFile* rom;
	if (game->data) {
		data = anonymousMemoryMap(game->size);
		dataSize = game->size;
		memcpy(data, game->data, game->size);
		rom = VFileFromMemory(data, game->size);
	} else {
		data = 0;
		rom = VFileOpen(game->path, O_RDONLY);
	}
	if (!rom) {
		return false;
	}

	core = mCoreFindVF(rom);
	if (!core) {
		rom->close(rom);
		mappedMemoryFree(data, game->size);
		return false;
	}
	mCoreInitConfig(core, NULL);
	core->init(core);
	core->setAVStream(core, &stream);

	size_t size = 256 * 224 * BYTES_PER_PIXEL;
	outputBuffer = malloc(size);
	memset(outputBuffer, 0xFF, size);
	core->setVideoBuffer(core, outputBuffer, 256);

	core->setAudioBufferSize(core, SAMPLES);

	blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768);
	blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768);

	core->setPeripheral(core, mPERIPH_RUMBLE, &rumble);

	savedata = anonymousMemoryMap(SIZE_CART_FLASH1M);
	struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M);

	_reloadSettings();
	core->loadROM(core, rom);
	core->loadSave(core, save);

	const char* sysDir = 0;
	const char* biosName = 0;
	char biosPath[PATH_MAX];
	environCallback(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysDir);

#ifdef M_CORE_GBA
	if (core->platform(core) == PLATFORM_GBA) {
		core->setPeripheral(core, mPERIPH_GBA_LUMINANCE, &lux);
		biosName = "gba_bios.bin";

	}
#endif

#ifdef M_CORE_GB
	if (core->platform(core) == PLATFORM_GB) {
		memset(&cam, 0, sizeof(cam));
		cam.height = GBCAM_HEIGHT;
		cam.width = GBCAM_WIDTH;
		cam.caps = 1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER;
		cam.frame_raw_framebuffer = _updateCamera;
		core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, &imageSource);

		environCallback(RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE, &cam);
		const char* modelName = mCoreConfigGetValue(&core->config, "gb.model");
		struct GB* gb = core->board;

		if (modelName) {
			gb->model = GBNameToModel(modelName);
		} else {
			GBDetectModel(gb);
		}

		switch (gb->model) {
		case GB_MODEL_AGB:
		case GB_MODEL_CGB:
			biosName = "gbc_bios.bin";
			break;
		case GB_MODEL_SGB:
			biosName = "sgb_bios.bin";
			break;
		case GB_MODEL_DMG:
		default:
			biosName = "gb_bios.bin";
			break;
		}
	}
#endif

	if (core->opts.useBios && sysDir && biosName) {
		snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, biosName);
		struct VFile* bios = VFileOpen(biosPath, O_RDONLY);
		if (bios) {
			core->loadBIOS(core, bios, 0);
		}
	}

	core->reset(core);
	_setupMaps(core);

	return true;
}
Example #12
0
File: main.c Project: yuriks/mgba
static void _setup(struct GBAGUIRunner* runner) {
	struct GBAOptions opts = {
		.useBios = true,
		.logLevel = 0,
		.idleOptimization = IDLE_LOOP_DETECT
	};
	GBAConfigLoadDefaults(&runner->context.config, &opts);
	runner->context.gba->logHandler = GBA3DSLog;
	runner->context.gba->rotationSource = &rotation.d;
	if (hasSound) {
		runner->context.gba->stream = &stream;
	}

	GBAVideoSoftwareRendererCreate(&renderer);
	renderer.outputBuffer = linearAlloc(256 * VIDEO_VERTICAL_PIXELS * 2);
	renderer.outputBufferStride = 256;
	runner->context.renderer = &renderer.d;

	GBAAudioResizeBuffer(&runner->context.gba->audio, AUDIO_SAMPLES);
}

static void _gameLoaded(struct GBAGUIRunner* runner) {
	if (runner->context.gba->memory.hw.devices & HW_TILT) {
		HIDUSER_EnableAccelerometer();
	}
	if (runner->context.gba->memory.hw.devices & HW_GYRO) {
		HIDUSER_EnableGyroscope();
	}

#if RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
	double ratio = GBAAudioCalculateRatio(1, 60, 1);
	blip_set_rates(runner->context.gba->audio.left,  GBA_ARM7TDMI_FREQUENCY, 0x8000 * ratio);
	blip_set_rates(runner->context.gba->audio.right, GBA_ARM7TDMI_FREQUENCY, 0x8000 * ratio);
#endif
	if (hasSound) {
		memset(audioLeft, 0, AUDIO_SAMPLES * sizeof(int16_t));
		memset(audioRight, 0, AUDIO_SAMPLES * sizeof(int16_t));
	}
}

static void _gameUnloaded(struct GBAGUIRunner* runner) {
	if (hasSound) {
		CSND_SetPlayState(8, 0);
		CSND_SetPlayState(9, 0);
		csndExecCmds(false);
	}

	if (runner->context.gba->memory.hw.devices & HW_TILT) {
		HIDUSER_DisableAccelerometer();
	}
	if (runner->context.gba->memory.hw.devices & HW_GYRO) {
		HIDUSER_DisableGyroscope();
	}
}

static void _drawFrame(struct GBAGUIRunner* runner, bool faded) {
	GX_SetDisplayTransfer(0, renderer.outputBuffer, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), tex->data, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), 0x000002202);
	GSPGPU_FlushDataCache(0, tex->data, 256 * VIDEO_VERTICAL_PIXELS * 2);
#if RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
	if (!hasSound) {
		blip_clear(runner->context.gba->audio.left);
		blip_clear(runner->context.gba->audio.right);
	}
#endif
	gspWaitForPPF();
	_drawStart();
	sf2d_draw_texture_scale_blend(tex, 40, 296, 1, -1, 0xFFFFFF3F | (faded ? 0 : 0xC0));
	_drawEnd();
}
Example #13
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);
}
Example #14
0
void retro_init(void) {
	enum retro_pixel_format fmt;
#ifdef COLOR_16_BIT
#ifdef COLOR_5_6_5
	fmt = RETRO_PIXEL_FORMAT_RGB565;
#else
#warning This pixel format is unsupported. Please use -DCOLOR_16-BIT -DCOLOR_5_6_5
	fmt = RETRO_PIXEL_FORMAT_0RGB1555;
#endif
#else
#warning This pixel format is unsupported. Please use -DCOLOR_16-BIT -DCOLOR_5_6_5
	fmt = RETRO_PIXEL_FORMAT_XRGB8888;
#endif
	environCallback(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt);

	struct retro_input_descriptor inputDescriptors[] = {
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "Brighten Solar Sensor" },
		{ 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "Darken Solar Sensor" }
	};
	environCallback(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, &inputDescriptors);

	// TODO: RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME when BIOS booting is supported

	struct retro_rumble_interface rumbleInterface;
	if (environCallback(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumbleInterface)) {
		rumbleCallback = rumbleInterface.set_rumble_state;
		CircleBufferInit(&rumbleHistory, RUMBLE_PWM);
		rumble.setRumble = _setRumble;
	} else {
		rumbleCallback = 0;
	}

	luxLevel = 0;
	lux.readLuminance = _readLux;
	lux.sample = _updateLux;
	_updateLux(&lux);

	struct retro_log_callback log;
	if (environCallback(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) {
		logCallback = log.log;
	} else {
		logCallback = 0;
	}

	stream.postAudioFrame = 0;
	stream.postAudioBuffer = _postAudioBuffer;
	stream.postVideoFrame = _postVideoFrame;

	GBACreate(&gba);
	ARMSetComponents(&cpu, &gba.d, 0, 0);
	ARMInit(&cpu);
	gba.logLevel = 0; // TODO: Settings
	gba.logHandler = GBARetroLog;
	gba.stream = &stream;
	gba.idleOptimization = IDLE_LOOP_REMOVE; // TODO: Settings
	if (rumbleCallback) {
		gba.rumble = &rumble;
	}
	gba.luminanceSource = &lux;
	rom = 0;

	const char* sysDir = 0;
	if (environCallback(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sysDir)) {
		char biosPath[PATH_MAX];
		snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, "gba_bios.bin");
		bios = VFileOpen(biosPath, O_RDONLY);
		if (bios) {
			GBALoadBIOS(&gba, bios);
		}
	}

	GBAVideoSoftwareRendererCreate(&renderer);
	renderer.outputBuffer = malloc(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
	renderer.outputBufferStride = 256;
	GBAVideoAssociateRenderer(&gba.video, &renderer.d);

	GBAAudioResizeBuffer(&gba.audio, SAMPLES);

#if RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
	blip_set_rates(gba.audio.left,  GBA_ARM7TDMI_FREQUENCY, 32768);
	blip_set_rates(gba.audio.right, GBA_ARM7TDMI_FREQUENCY, 32768);
#endif
}
Example #15
0
void init_audio_for_rom() {
    // Maximum number of unread samples the buffer can hold
    blip = blip_new(sample_rate/10);
    blip_set_rates(blip, cpu_clock_rate, sample_rate);
}