?? wildmidi.c
字號:
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 + -