Exemple #1
0
/**
 * audio_sdl_write_sound_buffer(): Write the sound buffer to the audio output.
 * @param dump_buf Sound dumping buffer.
 * @return 0 on success; non-zero on error.
 */
static int audio_sdl_write_sound_buffer(short *dump_buf)
{
	if (dump_buf)
	{
		if (audio_get_stereo())
			audio_dump_sound_stereo(dump_buf, audio_seg_length);
		else
			audio_dump_sound_mono(dump_buf, audio_seg_length);
		return 0;
	}
	
	SDL_LockAudio();
	
	if (audio_get_stereo())
	{
#ifdef GENS_X86_ASM
		if (CPU_Flags & MDP_CPUFLAG_X86_MMX)
			audio_write_sound_stereo_x86_mmx(Seg_L, Seg_R, (short*)(audio_sdl_audiobuf + audio_sdl_len), audio_seg_length);
		else
#endif
			audio_write_sound_stereo((short*)(audio_sdl_audiobuf + audio_sdl_len), audio_seg_length);
	}
	else
	{
#ifdef GENS_X86_ASM
		if (CPU_Flags & MDP_CPUFLAG_X86_MMX)
			audio_write_sound_mono_x86_mmx(Seg_L, Seg_R, (short*)(audio_sdl_audiobuf + audio_sdl_len), audio_seg_length);
		else
#endif
			audio_write_sound_mono((short*)(audio_sdl_audiobuf + audio_sdl_len), audio_seg_length);
	}
	
	if (audio_get_stereo())
		audio_sdl_len += audio_seg_length * 4;
	else
		audio_sdl_len += audio_seg_length * 2;
	
	SDL_UnlockAudio();
	
	// TODO: Figure out if there's a way to get rid of this.
	while (audio_sdl_len > 1024 * 2 * 2 * 4)
	{
		usleep(500);
		if (fast_forward)
			audio_sdl_len = 1024;
	} //SDL_Delay(1); 
	
	return 0;
}
Exemple #2
0
/**
 * wav_dump_update(): Update the WAV file.
 * @return 0 on success; non-zero on error.
 */
int wav_dump_update(void)
{
	if (!WAV_Dumping || !WAV_File)
	{
		if (WAV_File)
		{
			fclose(WAV_File);
			WAV_File = 0;
		}
		
		WAV_Dumping = 0;
		Sync_Gens_Window_SoundMenu();
		return 1;
	}
	
	// TODO: Byteswap on big-endian.
	short buf[(882 * 2) + 16];
	audio_write_sound_buffer(buf);
	
	unsigned int length = (audio_seg_length * 2);
	if (audio_get_stereo())
		length *= 2;
	
	/* Write the sound data. */
	fwrite(buf, 1, length, WAV_File);
	return 0;
}
Exemple #3
0
/**
 * audio_sdl_init(): Initialize the SDL audio subsystem.
 * @return 0 on success; non-zero on error.
 */
static int audio_sdl_init(void)
{
	if (audio_initialized)
		return -1;
	
	// Make sure sound is shut down first.
	audio_sdl_end();
	
	// Attempt to initialize SDL audio.
	if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
		return -1;
	
	// Set up the SDL audio specification.
	SDL_AudioSpec spec;
	spec.freq = audio_get_sound_rate();
	spec.format = AUDIO_S16SYS;
	spec.channels = !(audio_get_stereo()) ? 1 : 2; // TODO: Initializing 1 channel seems to double-free if it's later changed...
	spec.samples = 1024;
	spec.callback = audio_sdl_callback;
	spec.userdata = NULL;
	
	// Initialize the audio buffer.
	audio_sdl_audiobuf = (unsigned char*)(calloc(1, (spec.samples * spec.channels * 2 * 4) * sizeof(short)));
	
	if (SDL_OpenAudio(&spec, 0) != 0)
	{
		// Could not open audio.
		free(audio_sdl_audiobuf);
		audio_sdl_audiobuf = NULL;
		return -2;
	}
	SDL_PauseAudio(0);
	
	// Sound is initialized.
	audio_initialized = TRUE;
	return 0;
}
Exemple #4
0
/**
 * wav_dump_start(): Start dumping a WAV file.
 * @return 0 on success; non-zero on error.
 */
int wav_dump_start(void)
{
#ifdef GENS_OS_WIN32
	// Make sure relative pathnames are handled correctly on Win32.
	pSetCurrentDirectoryU(PathNames.Gens_Save_Path);
#endif
	
	/* A game must be loaded in order to dump a WAV. */
	if (!Game)
		return 0;
	
	if (WAV_Dumping)
	{
		vdraw_text_write("WAV sound is already dumping.", 1000);
		return 0;
	}
	
	/* Build the filename. */
	char filename[GENS_PATH_MAX];
	int num = -1;
	do
	{
		num++;
		szprintf(filename, sizeof(filename), "%s%s_%03d.wav", PathNames.Dump_WAV_Dir, ROM_Filename, num);
	} while (!access(filename, F_OK));
	
	/* Open the file. */
	WAV_File = fopen(filename, "wb");
	if (!WAV_File)
	{
		vdraw_text_write("Error opening WAV file.", 1000);
		return 1;
	}
	
	/* Create the WAV header. */
	memset(&WAV_Header, 0x00, sizeof(WAV_Header));
	
	/* "RIFF" header. */
	static const char ChunkID_RIFF[4] = {'R', 'I', 'F', 'F'};
	static const char FormatID_WAV[4] = {'W', 'A', 'V', 'E'};
	memcpy(WAV_Header.riff.ChunkID, ChunkID_RIFF, sizeof(WAV_Header.riff.ChunkID));
	memcpy(WAV_Header.riff.Format, FormatID_WAV, sizeof(WAV_Header.riff.Format));
	
	/* "fmt " header. */
	static const char SubchunkID_fmt[4] = {'f', 'm', 't', ' '};
	memcpy(WAV_Header.fmt.SubchunkID, SubchunkID_fmt, sizeof(WAV_Header.fmt.SubchunkID));
	WAV_Header.fmt.SubchunkSize	= cpu_to_le32(sizeof(WAV_Header.fmt) - 8);
	WAV_Header.fmt.AudioFormat	= cpu_to_le16(1); /* PCM */
	WAV_Header.fmt.NumChannels	= cpu_to_le16((audio_get_stereo() ? 2 : 1));
	WAV_Header.fmt.SampleRate	= cpu_to_le32(audio_get_sound_rate());
	WAV_Header.fmt.BitsPerSample	= cpu_to_le16(16); /* Gens is currently hard-coded to 16-bit audio. */
	
	/* Calculated fields. */
	WAV_Header.fmt.BlockAlign	= cpu_to_le16(WAV_Header.fmt.NumChannels * (WAV_Header.fmt.BitsPerSample / 8));
	WAV_Header.fmt.ByteRate		= cpu_to_le32(WAV_Header.fmt.BlockAlign * WAV_Header.fmt.SampleRate);
	
	/* "data" header. */
	static const char SubchunkID_data[4] = {'d', 'a', 't', 'a'};
	memcpy(WAV_Header.data.SubchunkID, SubchunkID_data, sizeof(WAV_Header.data.SubchunkID));
	
	/* Write the initial header to the file. */
	fwrite(&WAV_Header, sizeof(WAV_Header), 1, WAV_File);
	
	/* WAV dump started. */
	vdraw_text_write("Starting to dump WAV sound.", 1000);
	WAV_Dumping = 1;
	Sync_Gens_Window_SoundMenu();
	return 0;
}