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

📄 core.c

📁 Aqualung is an advanced music player primarily targeted for the GNU/Linux operating system, but als
💻 C
📖 第 1 页 / 共 5 页
字号:
#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;			default:				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;

⌨️ 快捷键说明

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