📄 audio.c
字号:
pb[0] = AL_CHANNEL_MODE; pb[1] = ((chan == 4) ? AL_4CHANNEL : AL_STEREO); if (ALsetparams(AL_DEFAULT_DEVICE, pb, 2)) RETURN_ERROR_EXIT(MUS_AUDIO_WRITE_ERROR, -1, mus_format("can't set default device to be %s", (chan == 4) ? "quad" : "stereo")); } else err = MUS_ERROR; } break; case MUS_AUDIO_AMP: fld = decode_field(dev, field, chan); if (fld != -1) { pb[0] = fld; if ((fld == AL_LEFT_SPEAKER_GAIN) || (fld == AL_RIGHT_SPEAKER_GAIN)) pb[1] = val[0] * MAX_VOLUME; else pb[1] = (1.0 - val[0]) * MAX_VOLUME; if (ALsetparams(AL_DEFAULT_DEVICE, pb, 2)) RETURN_ERROR_EXIT(MUS_AUDIO_WRITE_ERROR, -1, mus_format("can't set gain of %s", mus_audio_device_name(dev))); } else err = MUS_ERROR; break; case MUS_AUDIO_SRATE: fld = decode_field(dev, field, chan); if (fld != -1) { pb[0] = fld; pb[1] = val[0]; if (ALsetparams(AL_DEFAULT_DEVICE, pb, 2)) RETURN_ERROR_EXIT(MUS_AUDIO_WRITE_ERROR, -1, NULL); if (fld == AL_INPUT_RATE) { pb[0] = AL_OUTPUT_RATE; pb[1] = val[0]; if (ALsetparams(AL_DEFAULT_DEVICE, pb, 2)) RETURN_ERROR_EXIT(MUS_AUDIO_WRITE_ERROR, -1, mus_format("can't set srate of %s", mus_audio_device_name(dev))); } } else err = MUS_ERROR; break; default: err = MUS_ERROR; break; } if (err == MUS_ERROR) RETURN_ERROR_EXIT(MUS_AUDIO_CANT_WRITE, -1, mus_format("can't write %s setting of %s", mus_audio_device_name(field), mus_audio_device_name(dev))); end_sgi_print(); return(MUS_NO_ERROR);}static void describe_audio_state_1(void) { float amps[1]; int err; err = mus_audio_mixer_read(MUS_AUDIO_SPEAKERS, MUS_AUDIO_SRATE, 0, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, "srate: %.2f\n", amps[0]); pprint(audio_strbuf);} else {fprintf(stdout, "err: %d!\n", err); fflush(stdout);} err = mus_audio_mixer_read(MUS_AUDIO_SPEAKERS, MUS_AUDIO_AMP, 0, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, "speakers: %.2f", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_SPEAKERS, MUS_AUDIO_AMP, 1, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, " %.2f\n", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_LINE_IN, MUS_AUDIO_AMP, 0, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, "line in: %.2f", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_LINE_IN, MUS_AUDIO_AMP, 1, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, " %.2f\n", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_MICROPHONE, MUS_AUDIO_AMP, 0, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, "microphone: %.2f", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_MICROPHONE, MUS_AUDIO_AMP, 1, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, " %.2f\n", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_LINE_OUT, MUS_AUDIO_AMP, 0, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, "line out: %.2f", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_LINE_OUT, MUS_AUDIO_AMP, 1, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, " %.2f\n", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_DIGITAL_OUT, MUS_AUDIO_AMP, 0, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, "digital out: %.2f", amps[0]); pprint(audio_strbuf);} err = mus_audio_mixer_read(MUS_AUDIO_DIGITAL_OUT, MUS_AUDIO_AMP, 1, amps); if (err == MUS_NO_ERROR) {mus_snprintf(audio_strbuf, PRINT_BUFFER_SIZE, " %.2f\n", amps[0]); pprint(audio_strbuf);}}#endif/* new or old AL */#endif/* SGI *//* ------------------------------- OSS ----------------------------------------- */#if (HAVE_OSS || HAVE_ALSA || HAVE_JACK)/* actually it's not impossible that someday we'll have ALSA but not OSS... */#define AUDIO_OK#include <sys/ioctl.h>/* the system version of the soundcard header file may have no relation to the current OSS actually loaded *//* sys/soundcard.h is usually just a pointer to linux/soundcard.h */#if (MUS_HAVE_USR_LIB_OSS) #include "/usr/lib/oss/include/sys/soundcard.h"#else #if (MUS_HAVE_USR_LOCAL_LIB_OSS) #include "/usr/local/lib/oss/include/sys/soundcard.h" #else #if (MUS_HAVE_OPT_OSS) #include "/opt/oss/include/sys/soundcard.h" #else #if (MUS_HAVE_VAR_LIB_OSS) #include "/var/lib/oss/include/sys/soundcard.h" #else #if defined(HAVE_SYS_SOUNDCARD_H) || defined(MUS_LINUX) #include <sys/soundcard.h> #else #if defined(HAVE_MACHINE_SOUNDCARD_H) #include <machine/soundcard.h> #else #include <soundcard.h> #endif #endif #endif #endif #endif#endif#if ((SOUND_VERSION > 360) && (defined(OSS_SYSINFO))) #define NEW_OSS 1#endif#define DAC_NAME "/dev/dsp"#define MIXER_NAME "/dev/mixer"#define SYNTH_NAME "/dev/music"/* some programs use /dev/audio *//* there can be more than one sound card installed, and a card can be handled through * more than one /dev/dsp device, so we can't use a global dac device here. * The caller has to keep track of the various cards (via AUDIO_SYSTEM) -- * I toyed with embedding all that in mus_audio_open_output and mus_audio_write, but * decided it's better to keep them explicit -- the caller may want entirely * different (non-synchronous) streams going to the various cards. This same * code (AUDIO_SYSTEM(n)->devn) should work in Windoze (see below), and * might work on the Mac and SGI -- something for a rainy day... */#define RETURN_ERROR_EXIT(Message_Type, Audio_Line, Ur_Message) \ do { \ char *Message; Message = Ur_Message; \ if (Audio_Line != -1) \ linux_audio_close(Audio_Line); \ if ((Message) && (strlen(Message) > 0)) \ { \ mus_print("%s\n [%s[%d] %s]", \ Message, \ __FILE__, __LINE__, c__FUNCTION__); \ FREE(Message); \ } \ else mus_print("%s\n [%s[%d] %s]", \ mus_error_type_to_string(Message_Type), \ __FILE__, __LINE__, c__FUNCTION__); \ return(MUS_ERROR); \ } while (false)static int FRAGMENTS = 4;static int FRAGMENT_SIZE = 12;static bool fragments_locked = false;/* defaults here are FRAGMENTS 16 and FRAGMENT_SIZE 12; these values however * cause about a .5 second delay, which is not acceptable in "real-time" situations. * * this changed 22-May-01: these are causing more trouble than they're worth */static void oss_mus_oss_set_buffers(int num, int size) {FRAGMENTS = num; FRAGMENT_SIZE = size; fragments_locked = true;}#define MAX_SOUNDCARDS 8#define MAX_DSPS 8#define MAX_MIXERS 8/* there can be (apparently) any number of mixers and dsps per soundcard, but 8 is enough! */static int *audio_fd = NULL; static int *audio_open_ctr = NULL; static int *audio_dsp = NULL; static int *audio_mixer = NULL; static int *audio_mode = NULL; typedef enum {NORMAL_CARD, SONORUS_STUDIO, RME_HAMMERFALL, SAM9407_DSP, DELTA_66} audio_card_t;/* the Sonorus Studi/o card is a special case in all regards */static audio_card_t *audio_type = NULL; static int sound_cards = 0;static int new_oss_running = 0;static char *dev_name = NULL;static int oss_mus_audio_systems(void) { return(sound_cards);}static char *mixer_name(int sys){#if HAVE_SAM_9407 if((sys < sound_cards) && (audio_type[sys] == SAM9407_DSP)) { mus_snprintf(dev_name, LABEL_BUFFER_SIZE, "/dev/sam%d_mixer", audio_mixer[sys]); return(dev_name); }#endif if (sys < sound_cards) { if (audio_mixer[sys] == -2) return(MIXER_NAME); /* if we have /dev/dsp (not /dev/dsp0), I assume the corresponding mixer is /dev/mixer (not /dev/mixer0) */ /* but in sam9407 driver, there is no /dev/mixer, and everything goes through /dev/dsp */ else { if (audio_mixer[sys] == -3) return(DAC_NAME); else { mus_snprintf(dev_name, LABEL_BUFFER_SIZE, "%s%d", MIXER_NAME, audio_mixer[sys]); return(dev_name); } } } return(DAC_NAME);}static char *oss_mus_audio_system_name(int system) {#if HAVE_SAM_9407 if((system < sound_cards) && (audio_type[system] == SAM9407_DSP)) { int fd; fd = open(mixer_name(system), O_RDONLY, 0); if(fd != -1) { static SamDriverInfo driverInfo; if(ioctl(fd, SAM_IOC_DRIVER_INFO, &driverInfo) >= 0) { close(fd); return(driverInfo.hardware); } close(fd); } return("sam9407"); }#endif#ifdef NEW_OSS static mixer_info mixinfo; int status, ignored, fd; fd = open(mixer_name(system), O_RDONLY, 0); if (fd != -1) { status = ioctl(fd, OSS_GETVERSION, &ignored); if (status == 0) { status = ioctl(fd, SOUND_MIXER_INFO, &mixinfo); if (status == 0) { close(fd); return(mixinfo.name); } } close(fd); }#endif return("OSS");}#if HAVE_SAM_9407static char *oss_mus_audio_moniker(void) {return("Sam 9407");}#elsestatic char *oss_mus_audio_moniker(void){ char version[LABEL_BUFFER_SIZE]; if (version_name == NULL) version_name = (char *)CALLOC(LABEL_BUFFER_SIZE, sizeof(char)); if (SOUND_VERSION < 361) { mus_snprintf(version, LABEL_BUFFER_SIZE, "%d", SOUND_VERSION); mus_snprintf(version_name, LABEL_BUFFER_SIZE, "OSS %c.%c.%c", version[0], version[1], version[2]); } else mus_snprintf(version_name, LABEL_BUFFER_SIZE, "OSS %x.%x.%x", (SOUND_VERSION >> 16) & 0xff, (SOUND_VERSION >> 8) & 0xff, SOUND_VERSION & 0xff); return(version_name);}#endifstatic char *dac_name(int sys, int offset){#if HAVE_SAM_9407 if ((sys < sound_cards) && (audio_type[sys] == SAM9407_DSP)) { mus_snprintf(dev_name, LABEL_BUFFER_SIZE, "/dev/sam%d_dsp", audio_dsp[sys]); return(dev_name); }#endif if ((sys < sound_cards) && (audio_mixer[sys] >= -1)) { mus_snprintf(dev_name, LABEL_BUFFER_SIZE, "%s%d", DAC_NAME, audio_dsp[sys] + offset); return(dev_name); } return(DAC_NAME);}#define MIXER_SIZE SOUND_MIXER_NRDEVICESstatic int **mixer_state = NULL;static int *init_srate = NULL, *init_chans = NULL, *init_format = NULL;static int oss_mus_audio_initialize(void) { /* here we need to set up the map of /dev/dsp and /dev/mixer to a given system */ /* since this info is not passed to us by OSS, we have to work at it... */ /* for the time being, I'll ignore auxiliary dsp and mixer ports (each is a special case) */ int i, fd = -1, md, err = 0; char dname[LABEL_BUFFER_SIZE]; int amp, old_mixer_amp, old_dsp_amp, new_mixer_amp, responsive_field; int devmask;#ifdef NEW_OSS int status, ignored; oss_sysinfo sysinfo; static mixer_info mixinfo; int sysinfo_ok = 0;#endif int num_mixers, num_dsps, nmix, ndsp; if (!audio_initialized) { audio_initialized = true; audio_fd = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); audio_open_ctr = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); audio_dsp = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); audio_mixer = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); audio_type = (audio_card_t *)CALLOC(MAX_SOUNDCARDS, sizeof(audio_card_t)); audio_mode = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); dev_name = (char *)CALLOC(LABEL_BUFFER_SIZE, sizeof(char)); init_srate = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); init_chans = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); init_format = (int *)CALLOC(MAX_SOUNDCARDS, sizeof(int)); mixer_state = (int **)CALLOC(MAX_SOUNDCARDS, sizeof(int *)); for (i = 0; i < MAX_SOUNDCARDS; i++) mixer_state[i] = (int *)CALLOC(MIXER_SIZE, sizeof(int)); for (i = 0; i < MAX_SOUNDCARDS; i++) { audio_fd[i] = -1; audio_open_ctr[i] = 0; audio_dsp[i] = -1; audio_mixer[i] = -1; audio_type[i] = NORMAL_CARD; }#if HAVE_SAM_9407 { SamApiInfo apiInfo; SamDriverInfo driverInfo; for (i = 0; i < MAX_SOUNDCARDS; i++) { mus_snprintf(dname, LABEL_BUFFER_SIZE, "/dev/sam%d_mixer", i); fd = open(dname, O_WRONLY); if (fd < 0) break; if ((ioctl(fd, SAM_IOC_API_INFO, &apiInfo) < 0) || (apiInfo.apiClass!=SAM_API_CLASS_VANILLA) || (ioctl(fd, SAM_IOC_DRIVER_INFO, &driverInfo) < 0) || (!driverInfo.haveAudio)) { close(fd); continue; } audio_type[sound_cards] = SAM9407_DSP; audio_dsp[sound_cards] = i; audio_mixer[sound_cards] = i; sound_cards++; close(fd); } if(sound_cards > 0) return(0); }#endif num_mixers = MAX_MIXERS; num_dsps = MAX_DSPS;#ifdef NEW_OSS fd = open(DAC_NAME, O_WRONLY | O_NONBLOCK, 0); if (fd == -1) fd = open(SYNTH_NAME, O_RDONLY | O_NONBLOCK, 0); if (fd == -1) fd = open(MIXER_NAME, O_RDONLY | O_NONBLOCK, 0); if (fd != -1) { status = ioctl(fd, OSS_GETVERSION, &ignored); new_oss_running = (status == 0); if (new_oss_running) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -