⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wildmidi.c

📁 WildMidi Midi Library and Player
💻 C
📖 第 1 页 / 共 3 页
字号:
		LeaveCriticalSection(&waveCriticalSection);		while(!mm_free_blocks)			Sleep(10);		mm_current_block++;		mm_current_block %= MM_BLOCK_COUNT;		current = &mm_blocks[mm_current_block];		current->dwUser = 0;	}	return 0;}voidclose_mm_output ( void ) {	WAVEHDR* current;	int i, j;	current = &mm_blocks[mm_current_block];	i = MM_BLOCK_SIZE - current->dwUser;	for (j = i; i; i--) write_mm_output (0, 0);	waveOutClose (hWaveOut);	HeapFree(GetProcessHeap(), 0, mm_blocks);}#else#ifdef HAVE_ALSAvoid *buffer;int bps;int alsa_first_time = 1;static snd_pcm_t  *pcm;static snd_pcm_uframes_t alsa_period_size;static snd_pcm_channel_area_t *areas;int write_alsa_output (char * output_data, int output_size);void close_alsa_output ( void );intopen_alsa_output(void) {	snd_pcm_hw_params_t     *hw;	snd_pcm_sw_params_t     *sw;	int err;	int alsa_buffer_time, bits_per_sample;	unsigned int alsa_period_time;	snd_pcm_uframes_t alsa_buffer_size;		if (!pcmname)		pcmname = "default";			if ((err = snd_pcm_open (&pcm, pcmname, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {		printf("Error: audio open error: %s\n", snd_strerror (-err));		return -1;	} 		snd_pcm_hw_params_alloca (&hw);		if ((err = snd_pcm_hw_params_any(pcm, hw)) < 0) {		printf("ERROR: No configuration available for playback: %s\n", snd_strerror(-err));				return -1;	}	if ((err = snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {		printf("Cannot set mmap'ed mode: %s.\n", snd_strerror(-err));		return -1;	}		if (snd_pcm_hw_params_set_format (pcm, hw, SND_PCM_FORMAT_S16) < 0) {		printf("ALSA does not support 16bit signed audio for your soundcard\n");		close_alsa_output();		return -1;	}		if (snd_pcm_hw_params_set_channels (pcm, hw, 2) < 0) {		printf("ALSA does not support stereo for your soundcard\n");		close_alsa_output();		return -1;	}#ifdef ALSA_NEW	if (snd_pcm_hw_params_set_rate_near(pcm, hw, &rate, 0) < 0) {#else	if (snd_pcm_hw_params_set_rate_near(pcm, hw, rate, 0) < 0) {#endif		printf("ALSA does not support %iHz for your soundcard\n",rate);		close_alsa_output();		return -1;	}		alsa_buffer_time = 500000;	alsa_period_time = 50000;#ifdef ALSA_NEW		if ((err = snd_pcm_hw_params_set_buffer_time_near(pcm, hw, &alsa_buffer_time, 0)) < 0)#else	if ((err = snd_pcm_hw_params_set_buffer_time_near(pcm, hw, alsa_buffer_time, 0)) < 0)#endif	{		printf("Set buffer time failed: %s.\n", snd_strerror(-err));		return -1;	}#ifdef ALSA_NEW	if ((err = snd_pcm_hw_params_set_period_time_near(pcm, hw, &alsa_period_time, 0)) < 0)#else	if ((err = snd_pcm_hw_params_set_period_time_near(pcm, hw, alsa_period_time, 0)) < 0)#endif	{		printf("Set period time failed: %s.\n", snd_strerror(-err));		return -1;	}					if (snd_pcm_hw_params(pcm, hw) < 0)	{		printf("Unable to install hw params\n");		return -1;	}#ifdef ALSA_NEW	if ((err = snd_pcm_hw_params_get_buffer_size(hw, &alsa_buffer_size)) < 0)#else	if ((err = snd_pcm_hw_params_get_buffer_size(hw)) < 0)#endif	{		printf ("snd_pcm_hw_params_get_buffer_size() failed: %s\n", snd_strerror(-err));		return -1;	}#ifdef ALSA_NEW	if ((err = snd_pcm_hw_params_get_period_size(hw, &alsa_period_size, 0)) < 0)	#else	alsa_buffer_size = err;	if ((err = snd_pcm_hw_params_get_period_size(hw, 0)) < 0)#endif	{		printf ("snd_pcm_hw_params_get_period_size() failed: %s\n", snd_strerror(-err));		return -1;	}#ifndef ALSA_NEW	alsa_period_size = err;#endif		snd_pcm_sw_params_alloca(&sw);	snd_pcm_sw_params_current(pcm, sw);	if (snd_pcm_sw_params(pcm, sw) < 0)	{		printf("Unable to install sw params\n");		return -1;	}		bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16);	bps = (rate * bits_per_sample * 2) / 8000;	buffer = malloc(alsa_period_size * bits_per_sample / 8 * 2);	areas = malloc(2 * sizeof(snd_pcm_channel_area_t));	areas[0].addr = buffer;	areas[0].first = 0;	areas[0].step = 2 * bits_per_sample;	areas[1].addr = buffer;        areas[1].first = bits_per_sample;        areas[1].step = 2 * bits_per_sample;		send_output = write_alsa_output;	close_output = close_alsa_output;	return 0;			}int write_alsa_output (char * output_data, int output_size) {	int cnt = 0, err;	snd_pcm_uframes_t offset, frames;	snd_pcm_sframes_t avail;	const snd_pcm_channel_area_t *chan_areas = areas;		while (output_size > 0) {		avail = snd_pcm_avail_update(pcm);		if (avail == -EPIPE) {			if (snd_pcm_state(pcm) == SND_PCM_STATE_XRUN) {				if ((err = snd_pcm_prepare(pcm)) < 0)					printf("snd_pcm_prepare() failed.\n");				alsa_first_time = 1;			}		} else if (avail < 0) {			printf("snd_pcm_avail_update() failed: %s\n", snd_strerror(-avail));			avail = 0;		}		if (avail < alsa_period_size) {			usleep(500);			continue;		}		frames = snd_pcm_bytes_to_frames(pcm, output_size);		if ((err = snd_pcm_mmap_begin(pcm, &chan_areas, &offset, &frames)) < 0) {			printf("snd_pcm_mmap_begin() failed: %s\n", snd_strerror(-err));		}		cnt = snd_pcm_frames_to_bytes(pcm, frames);		memcpy((char*) chan_areas[0].addr + snd_pcm_frames_to_bytes(pcm, offset), output_data, cnt);		if ((err = snd_pcm_mmap_commit(pcm, offset, frames)) < 0) {			if (snd_pcm_state(pcm) == SND_PCM_STATE_XRUN) {				if ((err = snd_pcm_prepare(pcm)) < 0)					printf("snd_pcm_prepare() failed.\n");				alsa_first_time = 1;			}		}		if (err != frames)			printf("snd_pcm_mmap_commit returned %d, expected %d\n", err, (int)frames);				output_size -= cnt;		output_data += cnt;		if (alsa_first_time) {			alsa_first_time = 0;			snd_pcm_start(pcm);		}	}	return 0;}void close_alsa_output ( void ) {	snd_pcm_close (pcm);	free(areas);	free(buffer);}#else/* OSS Output Functions -------------------- uses mmap'd audio*/char *buffer = NULL;unsigned long int max_buffer;unsigned long int buffer_delay;unsigned long int counter;struct audio_buf_info info;int write_oss_output (char * output_data, int output_size);void close_oss_output ( void );intopen_oss_output( void ) {	int caps, rc, tmp;	unsigned long int omode = O_RDWR;	unsigned long int mmmode = PROT_WRITE | PROT_READ;	unsigned long int mmflags = MAP_FILE | MAP_SHARED;	unsigned long int sz = sysconf (_SC_PAGESIZE);	if (!pcmname)		pcmname = "/dev/dsp";	if ((audio_fd = open(pcmname, omode)) < 0) {		printf("ERROR: Unable to open /dev/dsp (%s)\n",strerror(errno));		return -1;			}	if (ioctl (audio_fd, SNDCTL_DSP_RESET, 0) < 0) {		printf("ERROR: Unable to reset /dev/dsp\n");		shutdown_output();		return -1;	}	if (ioctl (audio_fd, SNDCTL_DSP_GETCAPS, &caps) == -1) {		printf("ERROR: Driver Too Old\n");		shutdown_output();		return -1;	}	if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) {		printf ("Sound device can't do memory-mapped I/O.\n");		shutdown_output();		return -1;	}	if (ioctl (audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1) {		printf ("Um, can't do GETOSPACE?\n");		shutdown_output();		return -1;	}	max_buffer = (info.fragstotal * info.fragsize + sz - 1) & ~(sz - 1);		rc = AFMT_S16_LE;	if (ioctl (audio_fd, SNDCTL_DSP_SETFMT, &rc) < 0 ) {		printf("Can't set 16bit\n");		shutdown_output();;		return -1;	}	tmp = 2;	if (ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &tmp) < 0) {		printf("Can't set stereo\n");		shutdown_output();		return -1;	}			if (ioctl (audio_fd, SNDCTL_DSP_SPEED, &rate) < 0) {		printf("ERROR: /dev/dsp does not support %iHz output\n",rate);		shutdown_output();		return -1;	}				buffer = (unsigned char *) mmap(NULL, max_buffer, mmmode, mmflags, audio_fd, 0);	if (buffer == MAP_FAILED) {		printf("couldn't mmap %s\n",strerror(errno));		shutdown_output();		return -1;	}		tmp = 0;	if (ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp) < 0) {		printf("Couldn't toggle\n");		munmap (buffer, info.fragstotal * info.fragsize);		shutdown_output();		return -1;	}		tmp = PCM_ENABLE_OUTPUT;	if (ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp) < 0) {		printf("Couldn't toggle\n");		munmap (buffer, info.fragstotal * info.fragsize);		shutdown_output();		return -1;	}	buffer_delay = 1000000 / (rate / 4);	send_output = write_oss_output;	close_output = close_oss_output;	return 0;}intwrite_oss_output(char * output_data, int output_size) {	struct count_info count;	int data_read = 0;	int free_size = 0;	while (output_size != 0) {		while (1) {			if (ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) {				printf("Dead Sound\n");				munmap (buffer, info.fragstotal * info.fragsize);				shutdown_output();				return -1;			}			if ((count.ptr < counter) || (count.ptr >= (counter+4))) {				break;			}			usleep(500);		}		if (count.ptr < counter) {			free_size = max_buffer - counter;		} else {			free_size = count.ptr - counter;		}		if (free_size > output_size)			free_size = output_size;		memcpy(&buffer[counter], &output_data[data_read], free_size);		data_read += free_size;		counter += free_size;		if (counter >= max_buffer)			counter = 0;		output_size -= free_size;	}	return 0;}voidclose_oss_output(void) {	shutdown_output();	if (buffer != NULL)		munmap (buffer, info.fragstotal * info.fragsize);	audio_fd = -1;}#endif // HAVE_ALSA#endif/* ============================== ============================== ==============================*/static struct option const long_options[] = {	{"version",0,0,'v'},	{"help",0,0,'h'},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -