Esempio n. 1
0
void eof_mix_seek(int pos)
{
	int i;

	eof_log("eof_mix_seek() entered", 2);

	eof_mix_next_clap = -1;
	eof_mix_next_metronome = -1;
	eof_mix_next_note = -1;
	eof_mix_next_percussion = -1;

	eof_mix_sample_count = eof_mix_msec_to_sample(pos, alogg_get_wave_freq_ogg(eof_music_track));
	for(i = 0; i < eof_mix_claps; i++)
	{
		if(eof_mix_clap_pos[i] >= eof_mix_sample_count)
		{
			eof_mix_current_clap = i;
			eof_mix_next_clap = eof_mix_clap_pos[i];
			break;
		}
	}
	for(i = 0; i < eof_mix_metronomes; i++)
	{
		if(eof_mix_metronome_pos[i] >= eof_mix_sample_count)
		{
			eof_mix_current_metronome = i;
			eof_mix_next_metronome = eof_mix_metronome_pos[i];
			break;
		}
	}
	for(i = 0; i < eof_mix_notes; i++)
	{
		if(eof_mix_note_pos[i] >= eof_mix_sample_count)
		{
			eof_mix_current_note = i;
			eof_mix_next_note = eof_mix_note_pos[i];
			break;
		}
	}
	for(i = 0; i < eof_mix_percussions; i++)
	{
		if(eof_mix_percussion_pos[i] >= eof_mix_sample_count)
		{
			eof_mix_current_percussion = i;
			eof_mix_next_percussion = eof_mix_percussion_pos[i];
			break;
		}
	}
	for(i = 0; i < eof_mix_guitar_notes; i++)
	{
		if(eof_guitar_notes[i].pos >= eof_mix_sample_count)
		{
			eof_mix_current_guitar_note = i;
			eof_mix_next_guitar_note = eof_guitar_notes[i].pos;
			break;
		}
	}
}
Esempio n. 2
0
static unsigned long msec_to_samples(unsigned long msec)
{
	unsigned long sample;
	double second = (double)msec / (double)1000.0;
	unsigned long freq = alogg_get_wave_freq_ogg(eof_music_track);

	eof_log("msec_to_samples() entered", 1);

	sample = (unsigned long)(second * (double)freq);
	return sample;
}
Esempio n. 3
0
SAMPLE * create_silence_sample(unsigned long ms)
{
	SAMPLE * sp = NULL;
	int bits;
	int stereo;
	int freq;
	unsigned long samples, i;
	unsigned channels;

	eof_log("create_silence_sample() entered", 1);

	if(eof_music_track)
	{
		bits = alogg_get_wave_bits_ogg(eof_music_track);
		stereo = alogg_get_wave_is_stereo_ogg(eof_music_track);
		freq = alogg_get_wave_freq_ogg(eof_music_track);
		samples = msec_to_samples(ms);
		channels = stereo ? 2 : 1;
	}
	else
	{
		bits = 16;
		stereo = 1;
		freq = 44100;
		samples = (double)(ms * freq) / 1000.0;
		channels = 2;
	}

	sp = create_sample(bits, stereo, freq, samples);
	if(!sp)
		return NULL;	//Return error

	if(bits == 8)
	{
		for(i = 0; i < samples * channels; i++)
		{
			((unsigned char *)(sp->data))[i] = 0x80;
		}
	}
	else
	{
		for(i = 0; i < samples * channels; i++)
		{
			((unsigned short *)(sp->data))[i] = 0x8000;
		}
	}

	return sp;
}
Esempio n. 4
0
void eof_mix_start(int speed)
{
	unsigned long i;

	eof_log("eof_mix_start() entered", 1);

	eof_mix_next_clap = -1;
	eof_mix_next_metronome = -1;
	for(i = 0; i < EOF_MIX_MAX_CHANNELS; i++)
	{
		eof_voice[i].sp = NULL;
		eof_voice[i].pos = 0;
		eof_voice[i].fpos = 0.0;
		eof_voice[i].playing = 0;
		eof_voice[i].volume = 100;		//Default to 100% volume
		eof_voice[i].multiplier = 1.0;	//Default to 100% volume
	}
	eof_voice[0].volume = eof_clap_volume;	//Put the clap volume into effect
	eof_voice[0].multiplier = sqrt(eof_clap_volume/100.0);	//Store this math so it only needs to be performed once

	eof_voice[1].volume = eof_tick_volume;	//Put the tick volume into effect
	eof_voice[1].multiplier = sqrt(eof_tick_volume/100.0);	//Store this math so it only needs to be performed once

	eof_voice[2].volume = eof_tone_volume;	//Put the tone volume into effect
	eof_voice[2].multiplier = sqrt(eof_tone_volume/100.0);	//Store this math so it only needs to be performed once

	eof_voice[3].volume = eof_percussion_volume;	//Put the percussion volume into effect
	eof_voice[3].multiplier = sqrt(eof_percussion_volume/100.0);	//Store this math so it only needs to be performed once

	eof_mix_speed = speed;
	eof_mix_speed_ticker = 0;
	eof_mix_sample_count = eof_mix_msec_to_sample(alogg_get_pos_msecs_ogg(eof_music_track), alogg_get_wave_freq_ogg(eof_music_track));
	eof_mix_sample_increment = (1.0) * (44100.0 / (double)alogg_get_wave_freq_ogg(eof_music_track));
	eof_mix_start_helper();

	for(i = 1; i < eof_song->tracks; i++)
	{	//Pre-process all tracks so that switching tracks during playback doesn't cause the playback to lag
		eof_determine_phrase_status(eof_song, i);
	}
}
Esempio n. 5
0
int MYSTATICOGG::play_from(int position)
{
    if (use_extra_sound_offset) 
        extraOffset = ((16384 / (alogg_get_wave_is_stereo_ogg(tune) ? 2 : 1)) * 1000) / alogg_get_wave_freq_ogg(tune);
    else
        extraOffset = 0;

    if (alogg_play_ex_ogg(tune, 16384, vol, panning, 1000, repeat) != ALOGG_OK) {
        destroy();
        delete this;
        return 0;
    }

    last_ms_offs = position;
    last_but_one = position;
    last_but_one_but_one = position;

    if (position > 0)
        alogg_seek_abs_msecs_ogg(tune, position);

    if (!psp_audio_multithreaded)
      poll();

    return 1;
}
Esempio n. 6
0
int eof_add_silence_recode(char * oggfn, unsigned long ms)
{
	char sys_command[1024] = {0};
	char backupfn[1024] = {0};
	char wavfn[1024] = {0};
	char soggfn[1024] = {0};
	ALOGG_OGG *oggfile = NULL;
	SAMPLE *decoded = NULL, *combined = NULL;
	int bits;
	int stereo;
	int freq;
	unsigned long samples;
	int channels;
	unsigned long ctr,index;
	void * oggbuffer = NULL;
	int bitrate;

 	eof_log("eof_add_silence_recode() entered", 1);

	if(!oggfn || (ms == 0) || eof_silence_loaded)
	{
		return 41;	//Return failure:  Invalid parameters
	}
	set_window_title("Adjusting Silence...");

	/* back up original file */
	(void) snprintf(backupfn, sizeof(backupfn) - 1, "%s.backup", oggfn);
	if(!exists(backupfn))
	{
		(void) eof_copy_file(oggfn, backupfn);
	}

	/* Decode the OGG file into memory */
	//Load OGG file into memory
	oggbuffer = eof_buffer_file(oggfn, 0);	//Decode the OGG from buffer instead of from file because the latter cannot support special characters in the file path due to limitations with fopen()
	if(!oggbuffer)
	{
		(void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tError reading OGG:  \"%s\"", strerror(errno));	//Get the Operating System's reason for the failure
		eof_log(eof_log_string, 1);
		return 42;	//Return failure:  Could not buffer chart audio into memory
	}
	oggfile=alogg_create_ogg_from_buffer(oggbuffer, (int)file_size_ex(oggfn));
	if(oggfile == NULL)
	{
		eof_log("ALOGG failed to open input audio file", 1);
		free(oggbuffer);
		return 43;	//Return failure:  Could not process buffered chart audio
	}

	//Decode OGG into memory
	decoded=alogg_create_sample_from_ogg(oggfile);
	if(decoded == NULL)
	{
		alogg_destroy_ogg(oggfile);
		free(oggbuffer);
		return 44;	//Return failure:  Could not decode chart audio to memory
	}

	/* Create a SAMPLE array large enough for the leading silence and the decoded OGG */
	bits = alogg_get_wave_bits_ogg(oggfile);
	stereo = alogg_get_wave_is_stereo_ogg(oggfile);
	freq = alogg_get_wave_freq_ogg(oggfile);
	alogg_destroy_ogg(oggfile);	//This is no longer needed
	oggfile = NULL;
	samples = msec_to_samples(ms);
	channels = stereo ? 2 : 1;
	combined = create_sample(bits,stereo,freq,samples+decoded->len);	//Create a sample array long enough for the silence and the OGG file
	if(combined == NULL)
	{
		destroy_sample(decoded);
		return 45;	//Return failure:  Could not create a sample array for the combined audio
	}

	/* Add the PCM data for the silence */
	if(bits == 8)
	{	//Create 8 bit PCM data
		for(ctr=0,index=0;ctr < samples * channels;ctr++)
		{
			((unsigned char *)(combined->data))[index++] = 0x80;
		}
	}
	else
	{	//Create 16 bit PCM data
		for(ctr=0,index=0;ctr < samples * channels;ctr++)
		{
			((unsigned short *)(combined->data))[index++] = 0x8000;
		}
	}

	/* Add the decoded OGG PCM data*/
	if(bits == 8)
	{	//Copy 8 bit PCM data
		for(ctr=0;ctr < decoded->len * channels;ctr++)
		{
			((unsigned char *)(combined->data))[index++] = ((unsigned char *)(decoded->data))[ctr];
		}
	}
	else
	{	//Copy 16 bit PCM data
		for(ctr=0;ctr < decoded->len * channels;ctr++)
		{
			((unsigned short *)(combined->data))[index++] = ((unsigned short *)(decoded->data))[ctr];
		}
	}

	/* encode the audio */
	destroy_sample(decoded);	//This is no longer needed
	free(oggbuffer);
	(void) replace_filename(wavfn, eof_song_path, "encode.wav", 1024);
	(void) save_wav(wavfn, combined);
	destroy_sample(combined);	//This is no longer needed
	(void) replace_filename(soggfn, eof_song_path, "encode.ogg", 1024);
	bitrate = alogg_get_bitrate_ogg(eof_music_track) / 1000;
	if(!bitrate)
	{	//A user found that in an audio file with a really high sample rate (ie. 96KHz), alogg_get_bitrate_ogg() may return zero instead of an expected value
		bitrate = 256;	//In case this happens, use a bitrate of 256Kbps, which should be good enough for a very high quality file
	}
	#ifdef ALLEGRO_WINDOWS
		(void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -b %d \"%s\"", soggfn, bitrate, wavfn);
	#else
		(void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -b %d \"%s\"", soggfn, bitrate, wavfn);
	#endif

	(void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows:  %s", sys_command);
	eof_log(eof_log_string, 1);
	if(eof_system(sys_command))
	{	//If oggenc failed, retry again by specifying a quality level (specifying bitrate can fail in some circumstances)
		eof_log("\t\toggenc failed.  Retrying by specifying a quality level instead of a target bitrate", 1);
		#ifdef ALLEGRO_WINDOWS
			(void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -q 9 \"%s\"", soggfn, wavfn);
		#else
			(void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -q 9 \"%s\"", soggfn, wavfn);
		#endif
		(void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows:  %s", sys_command);
		eof_log(eof_log_string, 1);
		if(eof_system(sys_command))
		{	//If oggenc failed again
			char tempfname[30] = {0};
			char redirect[35] = {0};

			if(eof_validate_temp_folder())
			{	//Ensure the correct working directory and presence of the temporary folder
				eof_log("\tCould not validate working directory and temp folder", 1);
				return 46;	//Return failure:  Could not validate cwd and temp folder
			}

			(void) snprintf(tempfname, sizeof(tempfname) - 1, "%soggenc.log", eof_temp_path_s);
			(void) snprintf(redirect, sizeof(redirect) - 1, " 2> %s", tempfname);
			(void) ustrzcat(sys_command, (int) sizeof(sys_command) - 1, redirect);	//Append a redirection to the command to capture the output of oggenc
			if(eof_system(sys_command))
			{	//Run one last time to catch the error output
				(void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tOggenc failed.  Please see %s for any errors it gave.", tempfname);
				eof_log(eof_log_string, 1);
				eof_fix_window_title();
				return 47;	//Return failure:  Could not encode combined audio
			}
		}
	}

	/* replace the current OGG file with the new file */
	(void) eof_copy_file(soggfn, oggfn);	//Copy encode.ogg to the filename of the original OGG

	/* clean up */
	(void) delete_file(soggfn);	//Delete encode.ogg
	(void) delete_file(wavfn);		//Delete encode.wav
	if(eof_load_ogg(oggfn, 0))
	{	//If the combined audio was loaded
		eof_fix_waveform_graph();
		eof_fix_spectrogram();
		eof_fix_window_title();
		eof_chart_length = eof_music_length;
		return 0;	//Return success
	}
	eof_fix_window_title();

	return 48;	//Return error:  Could not load new audio
}
Esempio n. 7
0
/* process the Ogg from start_time to end_time, passing the decoded data to the supplied callback
   if the start and end time are the same value, the entire OGG is processed from the specified start time until the end of the file
   buffer_samples is the internally allocated buffer size to use */
int alogg_process_ogg(ALOGG_OGG * ogg, void(*callback)(void * buf, int nsamples, int stereo), int buffer_samples, double start_time, double end_time)
{
	int size_done, i, all_done = 0;
	int ret = 0;
	int bits;
	char * buffer;
	char * buffer_p;
	double current_pos;
	int buffer_bytes = buffer_samples * 2;
	unsigned long num_samples_left = 0, num_samples_decoded;
	char all = 0;	//Is set to nonzero if the OGG is to be processed until the end of the file

	buffer = malloc(buffer_bytes);
	if(!buffer)
	{
		return 0;
	}

	current_pos = ov_time_tell(&(ogg->vf));
	ov_time_seek(&(ogg->vf), start_time);

	if(start_time == end_time)
	{	//If the calling function intends to process the OGG until the end of the file
		all = 1;
	}
	else
	{
		num_samples_left = ((end_time - start_time) * alogg_get_wave_freq_ogg(ogg)) * (ogg->stereo ? 2 : 1);	//The number of samples to pass to the callback function
	}
	bits = alogg_get_wave_bits_ogg(ogg);	//The number of bits per sample (expected to be 16)
	if(bits != 16)
	{	//Unexpected sample size
		free(buffer);
		return 0;
	}

	while(!all_done)
	{
		buffer_p = buffer;
		for(i = 0; i < buffer_samples; i++)
		{	//Fill buffer with silent audio
			((unsigned short *)(buffer_p))[i] = 0x8000;
		}
		size_done = num_samples_decoded = 0;

		/* read samples from Ogg Vorbis file */
		for(i = buffer_bytes; i > 0; i -= size_done)
		{
			/* decode */
			size_done = ov_read(&(ogg->vf), buffer_p, i, alogg_endianess, 2, 0, &(ogg->current_section));

			/* check if the decoding was not successful */
			if(size_done < 0)
			{
				if(size_done == OV_HOLE)
				{
					size_done = 0;
				}
				else
				{
					all_done = 2;
				}
			}
			else if(size_done == 0)
			{	//No more samples
				all_done = 1;
				ret = 1;
				break; // playback finished so get out of loop
			}
			num_samples_decoded += size_done / 2;	//Keep track of how many samples have been decoded since the last callback
			buffer_p += size_done;
		}
		if(all || (num_samples_decoded < num_samples_left))
		{	//If all of the newly decoded samples are to be passed to the callback
		   callback(buffer, buffer_samples, ogg->stereo);
		   num_samples_left -= num_samples_decoded;
		}
		else
		{	//If the samples passed to the callback will be limited to the given time range
		   callback(buffer, num_samples_left, ogg->stereo);
		   all_done = 3;
		   ret = 1;
		}
	}
    free(buffer);
    ov_time_seek(&(ogg->vf), current_pos);
    return ret;
}
Esempio n. 8
0
void eof_mix_find_claps(void)
{
	unsigned long i;
	eof_mix_claps = 0;
	eof_mix_current_clap = 0;
	unsigned long tracknum;

	eof_log("eof_mix_find_claps() entered", 1);

	//Queue claps
	tracknum = eof_song->track[eof_selected_track]->tracknum;
	if(eof_vocals_selected)
	{
		for(i = 0; i < eof_song->vocal_track[tracknum]->lyrics; i++)
		{
			eof_mix_clap_pos[eof_mix_claps] = eof_mix_msec_to_sample(eof_song->vocal_track[tracknum]->lyric[i]->pos, alogg_get_wave_freq_ogg(eof_music_track));
			eof_mix_claps++;
		}
	}
	else
	{	//If a vocal track is not selected
		for(i = 0; i < eof_get_track_size(eof_song, eof_selected_track); i++)
		{	//For each note in the track
			if((eof_get_note_type(eof_song, eof_selected_track, i) == eof_note_type) && (eof_get_note_note(eof_song, eof_selected_track, i) & eof_mix_claps_note))
			{	//If the note is in the active track difficulty and the clap sound cue applies to at least one gem used in the note
				if(eof_clap_for_mutes || !(eof_get_note_flags(eof_song, eof_selected_track, i) & EOF_PRO_GUITAR_NOTE_FLAG_STRING_MUTE))
				{	//If clap cues should trigger for fully string muted notes, or if this note isn't fully string muted
					eof_mix_clap_pos[eof_mix_claps] = eof_mix_msec_to_sample(eof_get_note_pos(eof_song, eof_selected_track, i), alogg_get_wave_freq_ogg(eof_music_track));
					eof_mix_claps++;
				}
			}
		}
	}

	//Queue metronome
	eof_mix_metronomes = 0;
	eof_mix_current_metronome = 0;
	for(i = 0; i < eof_song->beats; i++)
	{
		eof_mix_metronome_pos[eof_mix_metronomes] = eof_mix_msec_to_sample(eof_song->beat[i]->pos, alogg_get_wave_freq_ogg(eof_music_track));
		eof_mix_metronomes++;
	}

	//Queue MIDI tones for pro guitar notes
	eof_mix_guitar_notes = 0;
	eof_mix_current_guitar_note = 0;
	if(eof_song->track[eof_selected_track]->track_format == EOF_PRO_GUITAR_TRACK_FORMAT)
	{	//If a pro guitar/bass track is active
		int tone = eof_midi_synth_instrument_guitar;
		EOF_PRO_GUITAR_TRACK *track = eof_song->pro_guitar_track[eof_song->track[eof_selected_track]->tracknum];

		if(track->arrangement == 4)
		{	//If this track's arrangement type is bass
			tone = eof_midi_synth_instrument_bass;	//Use the configured bass MIDI tone instead
		}
		for(i = 0; i < eof_get_track_size(eof_song, eof_selected_track); i++)
		{	//For each note in the track
			if(eof_get_note_type(eof_song, eof_selected_track, i) == eof_note_type)
			{	//If the note is in the active track difficulty
				int j = 0;
				unsigned long pos = eof_mix_msec_to_sample(eof_get_note_pos(eof_song, eof_selected_track, i) + eof_av_delay - eof_midi_tone_delay, alogg_get_wave_freq_ogg(eof_music_track));

				EOF_PRO_GUITAR_NOTE *note = track->note[i];
				for(j = 0; j < 6; j++)
				{	//For each of the 6 supported strings
					if((note->note & (1<<j)) && !(note->frets[j] & 0x80))
					{	//If the string is used (and not muted)
						eof_guitar_notes[eof_mix_guitar_notes].pos = pos;
						eof_guitar_notes[eof_mix_guitar_notes].channel = j;
						eof_guitar_notes[eof_mix_guitar_notes].note = track->tuning[j] + eof_lookup_default_string_tuning_absolute(track, eof_selected_track, j) + note->frets[j] + track->capo;
						eof_guitar_notes[eof_mix_guitar_notes].tone = tone;
						eof_mix_guitar_notes++;
					}
				}
			}
		}
	}

	//Queue vocal tones
	eof_mix_notes = 0;
	eof_mix_current_note = 0;
	eof_mix_percussions = 0;
	for(i = 0; i < eof_song->vocal_track[0]->lyrics; i++)
	{
		if((eof_song->vocal_track[0]->lyric[i]->note >= 36) && (eof_song->vocal_track[0]->lyric[i]->note <= 84))
		{	//This is a vocal pitch
			eof_mix_note_pos[eof_mix_notes] = eof_mix_msec_to_sample(eof_song->vocal_track[0]->lyric[i]->pos, alogg_get_wave_freq_ogg(eof_music_track));
			eof_mix_note_note[eof_mix_notes] = eof_song->vocal_track[0]->lyric[i]->note;
			eof_mix_note_ms_pos[eof_mix_notes] = eof_song->vocal_track[0]->lyric[i]->pos;
			eof_mix_note_ms_end[eof_mix_notes] = eof_song->vocal_track[0]->lyric[i]->pos + eof_song->vocal_track[0]->lyric[i]->length;
			eof_mix_notes++;
		}
		else if(eof_song->vocal_track[0]->lyric[i]->note == EOF_LYRIC_PERCUSSION)
		{	//This is vocal percussion
			eof_mix_percussion_pos[eof_mix_percussions] = eof_mix_msec_to_sample(eof_song->vocal_track[0]->lyric[i]->pos, alogg_get_wave_freq_ogg(eof_music_track));
			eof_mix_percussions++;
		}
	}
}