?? core.c
字號(hào):
#ifdef HAVE_ALSA/* return values: * 0 : success * -1 : device busy * -N : unable to start with given params */intalsa_init(thread_info_t * info, int verbose) { unsigned rate; int dir = 0; int ret; info->stream = SND_PCM_STREAM_PLAYBACK; snd_pcm_hw_params_alloca(&info->hwparams); ret = snd_pcm_open(&info->pcm_handle, info->pcm_name, info->stream, SND_PCM_NONBLOCK); if (ret < 0) { if (verbose) { fprintf(stderr, "alsa_init: error opening PCM device %s: %s\n", info->pcm_name, snd_strerror(ret)); } return -1; } snd_pcm_close(info->pcm_handle); /* now that we know the device is available, open it in blocking mode */ /* this is not deadlock safe. */ ret = snd_pcm_open(&info->pcm_handle, info->pcm_name, info->stream, 0); if (ret < 0) { if (verbose) { fprintf(stderr, "alsa_init: error reopening PCM device %s: %s\n", info->pcm_name, snd_strerror(ret)); } return -2; } if (snd_pcm_hw_params_any(info->pcm_handle, info->hwparams) < 0) { if (verbose) { fprintf(stderr, "alsa_init: cannot configure this PCM device.\n"); } return -3; } if (snd_pcm_hw_params_set_periods_integer(info->pcm_handle, info->hwparams) < 0) { fprintf(stderr, "alsa_init warning: cannot set period size to integer value.\n"); } if (snd_pcm_hw_params_set_access(info->pcm_handle, info->hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { if (verbose) { fprintf(stderr, "alsa_init: error setting access to SND_PCM_ACCESS_RW_INTERLEAVED.\n"); } return -4; } info->is_output_32bit = 1; if (snd_pcm_hw_params_set_format(info->pcm_handle, info->hwparams, SND_PCM_FORMAT_S32) < 0) { if (verbose) { fprintf(stderr, "alsa_init: unable to open 32 bit output, falling back to 16 bit...\n"); } if (snd_pcm_hw_params_set_format(info->pcm_handle, info->hwparams, SND_PCM_FORMAT_S16) < 0) { if (verbose) { fprintf(stderr, "alsa_init: unable to open 16 bit output, exiting.\n"); } return -5; } info->is_output_32bit = 0; } rate = info->out_SR; dir = 0; if (snd_pcm_hw_params_set_rate_near(info->pcm_handle, info->hwparams, &rate, &dir) < 0) { if (verbose) { fprintf(stderr, "alsa_init: can't set sample rate to %u.\n", rate); } return -6; } if (rate != info->out_SR) { if (verbose) { fprintf(stderr, "Requested sample rate (%ld Hz) cannot be set, ", info->out_SR); fprintf(stderr, "using closest available rate (%d Hz).\n", rate); } info->out_SR = rate; } if (snd_pcm_hw_params_set_channels(info->pcm_handle, info->hwparams, 2) < 0) { if (verbose) { fprintf(stderr, "alsa_init: error setting channels.\n"); } return -7; } if (snd_pcm_hw_params_set_periods(info->pcm_handle, info->hwparams, nperiods, 0) < 0) { if (verbose) { fprintf(stderr, "alsa_init warning: error setting nperiods to %d.\n", nperiods); } } if (snd_pcm_hw_params_set_buffer_size(info->pcm_handle, info->hwparams, (period * nperiods)>>2) < 0) { if (verbose) { fprintf(stderr, "alsa_init warning: failed setting buffersize to %d.\n", (period * nperiods)>>2); fprintf(stderr, "Parameters were: nperiods = %d, period = %d\n", nperiods, period); } } if (snd_pcm_hw_params(info->pcm_handle, info->hwparams) < 0) { if (verbose) { fprintf(stderr, "alsa_init: error setting HW params.\n"); } return -8; } return 0;}#endif /* HAVE_ALSA */#ifdef HAVE_JACK/* return values: * 0 : success * -1 : couldn't connect to Jack * -N : Jack sample rate (N) out of range */intjack_init(thread_info_t * info) { if (client_name == NULL) client_name = strdup("aqualung"); if ((jack_client = jack_client_new(client_name)) == 0) { return -1; } jack_set_process_callback(jack_client, process, info); jack_on_shutdown(jack_client, jack_shutdown, info); if ((info->out_SR = jack_get_sample_rate(jack_client)) > MAX_SAMPLERATE) { jack_client_close(jack_client); return -info->out_SR; } out_L_port = jack_port_register(jack_client, "out_L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); out_R_port = jack_port_register(jack_client, "out_R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); jack_nframes = jack_get_buffer_size(jack_client); if ((l_buf = malloc(jack_nframes * sizeof(float))) == NULL) { fprintf(stderr, "jack_init: malloc error\n"); exit(1); } if ((r_buf = malloc(jack_nframes * sizeof(float))) == NULL) { fprintf(stderr, "jack_init: malloc error\n"); exit(1); }#ifdef HAVE_LADSPA ladspa_buflen = jack_nframes;#endif /* HAVE_LADSPA */ return 0;}voidjack_client_start(void) { const char ** ports_out; if (jack_activate(jack_client)) { fprintf(stderr, "Cannot activate JACK client.\n"); exit(1); } if (auto_connect) { if (default_ports) { if ((ports_out = jack_get_ports(jack_client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { fprintf(stderr, "Cannot find any physical playback ports.\n"); } else { if (jack_connect(jack_client, jack_port_name(out_L_port), ports_out[0])) { fprintf(stderr, "Cannot connect out_L port to %s.\n", ports_out[0]); } else { fprintf(stderr, "Connected out_L to %s\n", ports_out[0]); } if (jack_connect(jack_client, jack_port_name(out_R_port), ports_out[1])) { fprintf(stderr, "Cannot connect out_R port to %s.\n", ports_out[1]); } else { fprintf(stderr, "Connected out_R to %s\n", ports_out[1]); } free(ports_out); } } else { if (jack_connect(jack_client, jack_port_name(out_L_port), user_port1)) { fprintf(stderr, "Cannot connect out_L port to %s.\n", user_port1); } else { fprintf(stderr, "Connected out_L to %s\n", user_port1); } if (jack_connect(jack_client, jack_port_name(out_R_port), user_port2)) { fprintf(stderr, "Cannot connect out_R port to %s.\n", user_port2); } else { fprintf(stderr, "Connected out_R to %s\n", user_port2); } } }}#endif /* HAVE_JACK */#ifdef _WIN32#define WIN32_BUFFER_LEN (1<<16)void *win32_thread(void * arg) { u_int32_t i; thread_info_t * info = (thread_info_t *)arg; WAVEFORMATEX wf; MMRESULT error; HWAVEOUT hwave; short * short_buf = NULL; int nbufs = 8; int bufcnt; WAVEHDR whdr[nbufs]; int j; int n_avail; char recv_cmd; int bufsize = WIN32_BUFFER_LEN / sizeof(short) / nbufs / 2; if ((l_buf = calloc(1, bufsize * sizeof(float))) == NULL) { fprintf(stderr, "win32_thread: malloc error\n"); exit(1); } if ((r_buf = calloc(1, bufsize * sizeof(float))) == NULL) { fprintf(stderr, "win32_thread: malloc error\n"); exit(1); }#ifdef HAVE_LADSPA ladspa_buflen = bufsize;#endif /* HAVE_LADSPA */ if ((short_buf = calloc(1, WIN32_BUFFER_LEN)) == NULL) { fprintf(stderr, "win32_thread: malloc error\n"); exit(1); } wf.nChannels = 2; wf.nSamplesPerSec = info->out_SR; wf.nBlockAlign = 2 * sizeof(short); wf.wFormatTag = WAVE_FORMAT_PCM; wf.cbSize = 0; wf.wBitsPerSample = 16; wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; error = waveOutOpen(&hwave, WAVE_MAPPER, &wf, 0L, 0L, 0L); if (error != MMSYSERR_NOERROR) { printf("waveOutOpen failed, error = %d\n", error); switch (error) { case MMSYSERR_ALLOCATED: puts("MMSYSERR_ALLOCATED"); break; case MMSYSERR_BADDEVICEID: puts("MMSYSERR_BADDEVICEID"); break; case MMSYSERR_NODRIVER: puts("MMSYSERR_NODRIVER"); break; case MMSYSERR_NOMEM: puts("MMSYSERR_NOMEM"); break; case WAVERR_BADFORMAT: puts("WAVERR_BADFORMAT"); break; case WAVERR_SYNC: puts("WAVERR_SYNC"); break; } return NULL; } for (bufcnt = 0; bufcnt < nbufs; bufcnt++) { whdr[bufcnt].lpData = (char *)short_buf + bufcnt * WIN32_BUFFER_LEN / nbufs; whdr[bufcnt].dwBufferLength = WIN32_BUFFER_LEN / nbufs; whdr[bufcnt].dwUser = 0L; whdr[bufcnt].dwFlags = 0L; whdr[bufcnt].dwLoops = 0L; if ((error = waveOutPrepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { printf("waveOutPrepareHeader[%d] failed : %08X\n", bufcnt, error); waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); waveOutClose(hwave); return NULL; } } for (j = 0; j < WIN32_BUFFER_LEN / sizeof(short); j++) { short_buf[j] = 0; } for (bufcnt = 0; bufcnt < nbufs; bufcnt++) { if ((error = waveOutWrite(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { printf("waveOutWrite[%d] failed : %08X\n", bufcnt, error); waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); waveOutClose(hwave); return NULL; } } bufcnt = 0; while (1) { win32_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 *)short_buf, 2*bufsize * sizeof(short)); } for (j = 0; j < WIN32_BUFFER_LEN / sizeof(short); j++) { short_buf[j] = 0; } goto win32_wake; break; case CMD_FINISH: goto win32_finish; break; fprintf(stderr, "win32_thread: recv'd unknown command %d\n", recv_cmd); break; } } if ((n_avail = rb_read_space(rb) / (2*sample_size)) == 0) { Sleep(100); goto win32_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 */ while (!(whdr[bufcnt].dwFlags & WHDR_DONE)) Sleep(1); 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; short_buf[2*bufcnt*bufsize + 2*i] = floorf(32767.0 * l_buf[i]); short_buf[2*bufcnt*bufsize + 2*i+1] = floorf(32767.0 * r_buf[i]); } /* write data to audio device */ if ((error = waveOutWrite(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR))) != MMSYSERR_NOERROR) { printf("waveOutWrite[%d] failed : %08X\n", bufcnt, error); waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); waveOutClose(hwave); return NULL; } ++bufcnt; if (bufcnt == nbufs) bufcnt = 0; } win32_finish: waveOutPause(hwave); waveOutReset(hwave); for (bufcnt = 0; bufcnt < nbufs; bufcnt++) { waveOutUnprepareHeader(hwave, &(whdr[bufcnt]), sizeof(WAVEHDR)); } waveOutClose(hwave); return 0;}#endif /* _WIN32 */ voidload_default_cl(int * argc, char *** argv) { int i = 0; char * home; xmlDocPtr doc; xmlNodePtr cur; xmlNodePtr root; xmlChar * key; FILE * f; char confdir[MAXLEN]; char config_file[MAXLEN]; char default_param[MAXLEN]; char cl[MAXLEN]; int ret; if (!(home = getenv("HOME"))) { fprintf(stderr, "Warning: $HOME not set, using \".\" (current directory) as home\n"); home = "."; } sprintf(confdir, "%s/.aqualung", home); if ((ret = chdir(confdir)) != 0) { if (errno == ENOENT) { fprintf(stderr, "Creating directory %s\n", confdir); mkdir(confdir, S_IRUSR | S_IWUSR | S_IXUSR); chdir(confdir); } else { fprintf(stderr, "An error occured while attempting chdir(\"%s\"). errno = %d\n", confdir, errno); } } sprintf(config_file, "%s/.aqualung/config.xml", home); if ((f = fopen(config_file, "rt")) == NULL) { fprintf(stderr, "No config.xml -- creating empty one: %s\n", config_file); fprintf(stderr, "Wired-in defaults will be used.\n"); doc = xmlNewDoc((const xmlChar *) "1.0"); root = xmlNewNode(NULL, (const xmlChar *) "aqualung_config"); xmlDocSetRootElement(doc, root); xmlSaveFormatFile(config_file, doc, 1); *argc = 1; return; } fclose(f); doc = xmlParseFile(config_file); if (doc == NULL) { fprintf(stderr, "An XML error occured while parsing %s\n", config_file); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "load_config: empty XML document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *)"aqualung_config")) { fprintf(stderr, "load_config: XML document of the wrong type, " "root node != aqualung_config\n"); xmlFreeDoc(doc); return; } default_param[0] = '\0'; cur = cur->xmlChildrenNode;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -