📄 core.c
字号:
if ((info->oss_short_buf = malloc(2*bufsize * sizeof(short))) == NULL) { fprintf(stderr, "oss_thread: malloc error\n"); exit(1); } oss_short_buf = info->oss_short_buf; if ((l_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "oss_thread: malloc error\n"); exit(1); } if ((r_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "oss_thread: malloc error\n"); exit(1); }#ifdef HAVE_LADSPA ladspa_buflen = bufsize;#endif /* HAVE_LADSPA */ while (1) { oss_wake: while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(short)) n_avail = 2*bufsize * sizeof(short); rb_read(rb, (char *)oss_short_buf, 2*bufsize * sizeof(short)); } goto oss_wake; break; case CMD_FINISH: goto oss_finish; break; default: fprintf(stderr, "oss_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { nanosleep(&req_time, &rem_time); goto oss_wake; } if (n_avail > bufsize) n_avail = bufsize; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); }#ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } }#else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; }#endif /* HAVE_LADSPA */ if (n_avail < bufsize) { for (i = n_avail; i < bufsize; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } /* plugin processing */#ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < bufsize; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } }#endif /* HAVE_LADSPA */ for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; oss_short_buf[2*i] = floorf(32767.0 * l_buf[i]); oss_short_buf[2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ ioctl_status = write(fd_oss, oss_short_buf, 2*n_avail * sizeof(short)); if (ioctl_status != 2*n_avail * sizeof(short)) fprintf(stderr, "oss_thread: Error writing to audio device\n"); } oss_finish: return 0;}#endif /* HAVE_OSS *//* ALSA output thread */#ifdef HAVE_ALSAvoid *alsa_thread(void * arg) { u_int32_t i; thread_info_t * info = (thread_info_t *)arg; snd_pcm_sframes_t n_written = 0; int bufsize = 1024; int n_avail; char recv_cmd; int is_output_32bit = info->is_output_32bit; short * alsa_short_buf = NULL; int * alsa_int_buf = NULL; snd_pcm_t * pcm_handle = info->pcm_handle; struct timespec req_time; struct timespec rem_time; req_time.tv_sec = 0; req_time.tv_nsec = 100000000; if (is_output_32bit) { if ((info->alsa_int_buf = malloc(2*bufsize * sizeof(int))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); } alsa_int_buf = info->alsa_int_buf; } else { if ((info->alsa_short_buf = malloc(2*bufsize * sizeof(short))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); } alsa_short_buf = info->alsa_short_buf; } if ((l_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); } if ((r_buf = malloc(bufsize * sizeof(float))) == NULL) { fprintf(stderr, "alsa_thread: malloc error\n"); exit(1); }#ifdef HAVE_LADSPA ladspa_buflen = bufsize;#endif /* HAVE_LADSPA */ while (1) { alsa_wake: while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: if (is_output_32bit) { while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(int)) n_avail = 2*bufsize * sizeof(int); rb_read(rb, (char *)alsa_int_buf, 2*bufsize * sizeof(int)); } } else { while ((n_avail = rb_read_space(rb)) > 0) { if (n_avail > 2*bufsize * sizeof(short)) n_avail = 2*bufsize * sizeof(short); rb_read(rb, (char *)alsa_short_buf, 2*bufsize * sizeof(short)); } } goto alsa_wake; break; case CMD_FINISH: goto alsa_finish; break; default: fprintf(stderr, "alsa_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { nanosleep(&req_time, &rem_time); goto alsa_wake; } if (n_avail > bufsize) n_avail = bufsize; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); }#ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } }#else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; }#endif /* HAVE_LADSPA */ if (n_avail < bufsize) { for (i = n_avail; i < bufsize; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } /* plugin processing */#ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < bufsize; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } }#endif /* HAVE_LADSPA */ if (is_output_32bit) { for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; alsa_int_buf[2*i] = floorf(2147483647.0 * l_buf[i]); alsa_int_buf[2*i+1] = floorf(2147483647.0 * r_buf[i]); } /* write data to audio device */ if ((n_written = snd_pcm_writei(pcm_handle, alsa_int_buf, n_avail)) != n_avail) { snd_pcm_prepare(pcm_handle); } } else { for (i = 0; i < bufsize; i++) { if (l_buf[i] > 1.0) l_buf[i] = 1.0; else if (l_buf[i] < -1.0) l_buf[i] = -1.0; if (r_buf[i] > 1.0) r_buf[i] = 1.0; else if (r_buf[i] < -1.0) r_buf[i] = -1.0; alsa_short_buf[2*i] = floorf(32767.0 * l_buf[i]); alsa_short_buf[2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ if ((n_written = snd_pcm_writei(pcm_handle, alsa_short_buf, n_avail)) != n_avail) { snd_pcm_prepare(pcm_handle); } } } alsa_finish: return 0;}#endif /* HAVE_ALSA *//* JACK output function */#ifdef HAVE_JACKintprocess(u_int32_t nframes, void * arg) { u_int32_t i; u_int32_t n_avail; jack_default_audio_sample_t * out1 = jack_port_get_buffer(out_L_port, nframes); jack_default_audio_sample_t * out2 = jack_port_get_buffer(out_R_port, nframes); static int flushing = 0; static int flushcnt = 0; char recv_cmd; jack_nframes = nframes;#ifdef HAVE_LADSPA ladspa_buflen = nframes;#endif /* HAVE_LADSPA */ while (rb_read_space(rb_disk2out)) { rb_read(rb_disk2out, &recv_cmd, 1); switch (recv_cmd) { case CMD_FLUSH: flushing = 1; flushcnt = rb_read_space(rb)/nframes/ (2*sample_size) * 1.1f; break; case CMD_FINISH: return 0; break; default: fprintf(stderr, "jack process(): recv'd unknown command %d\n", recv_cmd); break; } } n_avail = rb_read_space(rb) / (2*sample_size); if (n_avail > nframes) n_avail = nframes; for (i = 0; i < n_avail; i++) { rb_read(rb, (char *)&(l_buf[i]), sample_size); rb_read(rb, (char *)&(r_buf[i]), sample_size); } if (n_avail < nframes) { for (i = n_avail; i < nframes; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } if (flushing) { for (i = 0; i < n_avail; i++) { l_buf[i] = 0.0f; r_buf[i] = 0.0f; } } else {#ifdef HAVE_LADSPA if (options.ladspa_is_postfader) { for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } }#else for (i = 0; i < n_avail; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; }#endif /* HAVE_LADSPA */ /* plugin processing */#ifdef HAVE_LADSPA plugin_lock = 1; for (i = 0; i < n_plugins; i++) { if (plugin_vect[i]->is_bypassed) continue; if (plugin_vect[i]->handle) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle, ladspa_buflen); } if (plugin_vect[i]->handle2) { plugin_vect[i]->descriptor->run(plugin_vect[i]->handle2, ladspa_buflen); } } plugin_lock = 0; if (!options.ladspa_is_postfader) { for (i = 0; i < nframes; i++) { l_buf[i] *= left_gain; r_buf[i] *= right_gain; } }#endif /* HAVE_LADSPA */ } for (i = 0; i < nframes; i++) { out1[i] = l_buf[i]; out2[i] = r_buf[i]; } if ((flushing) && (!rb_read_space(rb) || (--flushcnt == 0))) { flushing = 0; } return 0;}voidjack_shutdown(void * arg) { jack_is_shutdown = 1;}#endif /* HAVE_JACK */#ifdef HAVE_OSS/* return values: * 0 : success * -1 : device busy * -N : unable to start with given params */intoss_init(thread_info_t * info, int verbose) { int ioctl_arg; int ioctl_status; if (info->out_SR > MAX_SAMPLERATE) { if (verbose) { fprintf(stderr, "\nThe sample rate you set (%ld Hz) is higher than MAX_SAMPLERATE.\n", info->out_SR); fprintf(stderr, "This is an arbitrary limit, which you may safely enlarge " "if you really need to.\n"); fprintf(stderr, "Currently MAX_SAMPLERATE = %d Hz.\n", MAX_SAMPLERATE); } return -2; } /* open dsp device */ info->fd_oss = open(device_name, O_WRONLY, 0); if (info->fd_oss < 0) { if (verbose) { fprintf(stderr, "oss_init: open of %s ", device_name); perror("failed"); } return -1; } ioctl_arg = 16; /* bitdepth */ ioctl_status = ioctl(info->fd_oss, SOUND_PCM_WRITE_BITS, &ioctl_arg); if (ioctl_status == -1) { if (verbose) { perror("oss_init: SOUND_PCM_WRITE_BITS ioctl failed"); } return -3; } if (ioctl_arg != 16) { if (verbose) { perror("oss_init: unable to set sample size"); } return -4; } ioctl_arg = 2; /* stereo */ ioctl_status = ioctl(info->fd_oss, SOUND_PCM_WRITE_CHANNELS, &ioctl_arg); if (ioctl_status == -1) { if (verbose) { perror("oss_init: SOUND_PCM_WRITE_CHANNELS ioctl failed"); } return -5; } if (ioctl_arg != 2) { if (verbose) { perror("oss_init: unable to set number of channels"); } return -6; } ioctl_arg = info->out_SR; ioctl_status = ioctl(info->fd_oss, SOUND_PCM_WRITE_RATE, &ioctl_arg); if (ioctl_status == -1) { if (verbose) { perror("oss_init: SOUND_PCM_WRITE_RATE ioctl failed"); } return -7; } if (ioctl_arg != info->out_SR) { if (verbose) { fprintf(stderr, "oss_init: unable to set sample_rate to %ld\n", info->out_SR); } return -8; } /* start OSS output thread */ AQUALUNG_THREAD_CREATE(info->oss_thread_id, NULL, oss_thread, info) return 0;}#endif /* HAVE_OSS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -