📄 audio.c
字号:
device = (long *)CALLOC(IO_LINES, sizeof(long)); datum_size = (int *)CALLOC(IO_LINES, sizeof(int)); line_out = (int *)CALLOC(IO_LINES, sizeof(int)); } return(MUS_NO_ERROR);}#ifdef AL_RESOURCEstatic int to_al_interface_or_device(int dev, int which){ switch (dev) { case MUS_AUDIO_DEFAULT: case MUS_AUDIO_DUPLEX_DEFAULT: return(AL_DEFAULT_OUTPUT); break; case MUS_AUDIO_DAC_OUT: case MUS_AUDIO_SPEAKERS: return(alGetResourceByName(AL_SYSTEM, "Analog Out", which)); break; case MUS_AUDIO_MICROPHONE: return(alGetResourceByName(AL_SYSTEM, "Microphone", which)); break; case MUS_AUDIO_ADAT_IN: return(alGetResourceByName(AL_SYSTEM, "ADAT In", which)); break; case MUS_AUDIO_AES_IN: return(alGetResourceByName(AL_SYSTEM, "AES In", which)); break; case MUS_AUDIO_ADAT_OUT: return(alGetResourceByName(AL_SYSTEM, "ADAT Out", which)); break; case MUS_AUDIO_DIGITAL_OUT: case MUS_AUDIO_AES_OUT: return(alGetResourceByName(AL_SYSTEM, "AES Out", which)); break; case MUS_AUDIO_LINE_IN: return(alGetResourceByName(AL_SYSTEM, "Line In", which)); break; case MUS_AUDIO_LINE_OUT: return(alGetResourceByName(AL_SYSTEM, "Line Out2", which)); break; /* ?? */ /* case MUS_AUDIO_DIGITAL_IN: return(alGetResourceByName(AL_SYSTEM, "DAC2 In", which)); break; */ /* this is analog in ?? */ } return(MUS_ERROR);}static int to_al_device(int dev) { return(to_al_interface_or_device(dev, AL_DEVICE_TYPE));}static int to_al_interface(int dev) { return(to_al_interface_or_device(dev, AL_INTERFACE_TYPE));}#endif#include <stdio.h>/* just a placeholder for now */int find_audio_output(int chans){#ifdef AL_RESOURCE ALvalue x[32]; ALpv y; int n, i; y.param = AL_INTERFACE; y.value.i = AL_DIGITAL_IF_TYPE; n = alQueryValues(AL_SYSTEM, AL_DEFAULT_OUTPUT, x, 32, &y, 1); for (i = 0; i < n; i++) { y.param = AL_CHANNELS; alGetParams(x[i].i, &y, 1); if (chans <= y.value.i) return(x[i].i); }#endif return(MUS_ERROR);}static int to_sgi_format(int frm){ switch (frm) { case MUS_BYTE: case MUS_BSHORT: case MUS_B24INT: return(AL_SAMPFMT_TWOSCOMP); break; case MUS_BFLOAT: return(AL_SAMPFMT_FLOAT); break; case MUS_BDOUBLE: return(AL_SAMPFMT_DOUBLE); break; } return(MUS_ERROR);}int mus_audio_open_output(int ur_dev, int srate, int chans, int format, int requested_size){#ifdef AL_RESOURCE ALpv z[2];#endif long sr[2]; int i, line, size, width, sgi_format, dev; start_sgi_print(); dev = MUS_AUDIO_DEVICE(ur_dev); line = -1; for (i = 0; i < IO_LINES; i++) if (line_in_use[i] == 0) { line = i; break; } if (line == -1) RETURN_ERROR_EXIT(MUS_AUDIO_NO_LINES_AVAILABLE, line, "no free audio lines?"); channels[line] = chans; line_out[line] = 1; if (requested_size == 0) size = 1024 * chans; else size = check_queue_size(requested_size, chans); /* if (chans > 2) size = 65536; */ /* for temp adat code */ datum_size[line] = mus_bytes_per_sample(format); if (datum_size[line] == 3) width = AL_SAMPLE_24; else { if (datum_size[line] == 1) width = AL_SAMPLE_8; else width = AL_SAMPLE_16; } sgi_format = to_sgi_format(format); if (sgi_format == MUS_ERROR) RETURN_ERROR_EXIT(MUS_AUDIO_FORMAT_NOT_AVAILABLE, -1, mus_format("format %d (%s) not supported by SGI", format, mus_audio_format_name(format)));#ifdef AL_RESOURCE if (dev == MUS_AUDIO_DEFAULT) device[line] = AL_DEFAULT_OUTPUT; else device[line] = to_al_device(dev); if (!(device[line])) RETURN_ERROR_EXIT(MUS_AUDIO_DEVICE_NOT_AVAILABLE, -1, mus_format("device %d (%s) not available", dev, mus_audio_device_name(dev)));#if 0 if (device_channels(dev) < chans) /* look for some device that can play this file */ device[line] = find_audio_output(chans); if (device[line] == -1) RETURN_ERROR_EXIT(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, -1, mus_format("can't find %d channel device", chans));#endif if ((chans == 4) && (dev == MUS_AUDIO_DAC_OUT)) { /* kludge around a bug in the new audio library */ sr[0] = AL_CHANNEL_MODE; sr[1] = AL_4CHANNEL; ALsetparams(AL_DEFAULT_DEVICE, sr, 2); } z[0].param = AL_RATE; z[0].value.ll = alDoubleToFixed((double)srate); z[1].param = AL_MASTER_CLOCK; /* z[1].value.i = AL_CRYSTAL_MCLK_TYPE; */ z[1].value.i = AL_MCLK_TYPE; /* was AL_CRYSTAL_MCLK_TYPE -- digital I/O perhaps needs AL_VARIABLE_MCLK_TYPE */ if (alSetParams(device[line], z, 2) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_SRATE_NOT_AVAILABLE, -1, mus_format("can't set srate of %s to %d", mus_audio_device_name(dev), srate));#else device[line] = AL_DEFAULT_DEVICE; check_quad(device[line], chans); sr[0] = AL_OUTPUT_RATE; sr[1] = srate; if (ALsetparams(device[line], sr, 2) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_SRATE_NOT_AVAILABLE, -1, mus_format("can't set srate of %s to %d", mus_audio_device_name(dev), srate));#endif config[line] = al_newconfig(); if (!(config[line])) RETURN_ERROR_EXIT(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, -1, "can't allocate audio configuration?"); if ((al_setsampfmt(config[line], sgi_format) == -1) || (al_setwidth(config[line], width) == -1)) /* this is a no-op in the float and double cases */ RETURN_ERROR_EXIT(MUS_AUDIO_FORMAT_NOT_AVAILABLE, line, mus_format("audio format %d (%s, SGI: %d) not available on device %d (%s)", format, mus_audio_format_name(format), sgi_format, dev, mus_audio_device_name(dev))); if (al_setchannels(config[line], chans) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, line, mus_format("can't get %d channels on device %d (%s)", chans, dev, mus_audio_device_name(dev))); /* set queue size probably needs a check first for legal queue sizes given the current desired device */ /* in new AL, I'm assuming above (check_queue_size) that it needs at least 1024 per chan */ if (al_setqueuesize(config[line], size) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_SIZE_NOT_AVAILABLE, line, mus_format("can't get queue size %d on device %d (%s) (chans: %d, requested_size: %d)", size, dev, mus_audio_device_name(dev), chans, requested_size));#ifdef AL_RESOURCE if (alSetDevice(config[line], device[line]) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_DEVICE_NOT_AVAILABLE, line, mus_format("can't get device %d (%s)", dev, mus_audio_device_name(dev)));#endif port[line] = al_openport("dac", "w", config[line]); if (!(port[line])) RETURN_ERROR_EXIT(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, line, mus_format("can't open output port on device %d (%s)", dev, mus_audio_device_name(dev))); line_in_use[line] = 1; end_sgi_print(); return(line);}int mus_audio_write(int line, char *buf, int bytes){ start_sgi_print();#ifdef AL_RESOURCE if (alWriteFrames(port[line], (short *)buf, bytes / (channels[line] * datum_size[line])))#else if (ALwritesamps(port[line], (short *)buf, bytes / datum_size[line]))#endif RETURN_ERROR_EXIT(MUS_AUDIO_WRITE_ERROR, -1, "write error"); end_sgi_print(); return(MUS_NO_ERROR);}int mus_audio_close(int line){ int err; start_sgi_print(); if (line_in_use[line]) { if (line_out[line]) while (al_getfilled(port[line]) > 0) sginap(1); err = ((al_closeport(port[line])) || (al_freeconfig(config[line]))); line_in_use[line] = 0; if (err) RETURN_ERROR_EXIT(MUS_AUDIO_CANT_CLOSE, -1, mus_format("can't close audio port %p (line %d)", port[line], line)); } end_sgi_print(); return(MUS_NO_ERROR);}int mus_audio_open_input(int ur_dev, int srate, int chans, int format, int requested_size){ int dev;#ifdef AL_RESOURCE ALpv pv; ALpv x[2];#else long sr[2]; int resind;#endif int i, line, sgi_format; start_sgi_print(); dev = MUS_AUDIO_DEVICE(ur_dev); line = -1; for (i = 0; i < IO_LINES; i++) if (line_in_use[i] == 0) { line = i; break; } if (line == -1) RETURN_ERROR_EXIT(MUS_AUDIO_NO_LINES_AVAILABLE, -1, "no free audio lines?"); channels[line] = chans; line_out[line] = 0; datum_size[line] = mus_bytes_per_sample(format);#ifdef AL_RESOURCE if (dev == MUS_AUDIO_DEFAULT) device[line] = AL_DEFAULT_INPUT; else { int itf; device[line] = to_al_device(dev); itf = to_al_interface(dev); if (itf) { pv.param = AL_INTERFACE; pv.value.i = itf; if (alSetParams(device[line], &pv, 1) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, -1, mus_format("can't set up device %d (%s)", dev, mus_audio_device_name(dev))); } } if (!(device[line])) RETURN_ERROR_EXIT(MUS_AUDIO_DEVICE_NOT_AVAILABLE, -1, mus_format("can't get input device %d (%s)", dev, mus_audio_device_name(dev))); x[0].param = AL_RATE; x[0].value.ll = alDoubleToFixed((double)srate); x[1].param = AL_MASTER_CLOCK; x[1].value.i = AL_MCLK_TYPE; /* AL_CRYSTAL_MCLK_TYPE; */ if (alSetParams(device[line], x, 2) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_SRATE_NOT_AVAILABLE, -1, mus_format("can't set srate of %s to %d", mus_audio_device_name(dev), srate));#else switch (dev) { case MUS_AUDIO_DEFAULT: case MUS_AUDIO_DUPLEX_DEFAULT: case MUS_AUDIO_MICROPHONE: resind = AL_INPUT_MIC; break; case MUS_AUDIO_LINE_IN: resind = AL_INPUT_LINE; break; case MUS_AUDIO_DIGITAL_IN: resind = AL_INPUT_DIGITAL; break; default: RETURN_ERROR_EXIT(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, -1, mus_format("audio input device %d (%s) not available", dev, mus_audio_device_name(dev))); break; } device[line] = AL_DEFAULT_DEVICE; sr[0] = AL_INPUT_SOURCE; sr[1] = resind; if (ALsetparams(device[line], sr, 2) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, -1, mus_format("can't set up input device %d (%s)", dev, mus_audio_device_name(dev))); check_quad(device[line], chans); sr[0] = AL_INPUT_RATE; sr[1] = srate; if (ALsetparams(device[line], sr, 2) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_SRATE_NOT_AVAILABLE, -1, mus_format("can't set srate of %s to %d", mus_audio_device_name(dev), srate));#endif config[line] = al_newconfig(); if (!(config[line])) RETURN_ERROR_EXIT(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, -1, "can't allocate audio configuration?"); sgi_format = to_sgi_format(format); if (sgi_format == MUS_ERROR) RETURN_ERROR_EXIT(MUS_AUDIO_FORMAT_NOT_AVAILABLE, -1, mus_format("format %d (%s) not supported by SGI", format, mus_audio_format_name(format))); if ((al_setsampfmt(config[line], sgi_format) == -1) || (al_setwidth(config[line], (datum_size[line] == 2) ? AL_SAMPLE_16 : AL_SAMPLE_8) == -1)) RETURN_ERROR_EXIT(MUS_AUDIO_FORMAT_NOT_AVAILABLE, line, mus_format("audio format %d (%s, SGI: %d) not available on device %d (%s)", format, mus_audio_format_name(format), sgi_format, dev, mus_audio_device_name(dev))); if (al_setchannels(config[line], chans) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_CHANNELS_NOT_AVAILABLE, line, mus_format("can't get %d channels on device %d (%s)", chans, dev, mus_audio_device_name(dev)));#ifdef AL_RESOURCE if (alSetDevice(config[line], device[line]) == -1) RETURN_ERROR_EXIT(MUS_AUDIO_DEVICE_NOT_AVAILABLE, line, mus_format("can't get device %d (%s)", dev, mus_audio_device_name(dev)));#endif port[line] = al_openport("adc", "r", config[line]); if (!(port[line])) RETURN_ERROR_EXIT(MUS_AUDIO_CONFIGURATION_NOT_AVAILABLE, line, mus_format("can't open input port on device %d (%s)", dev, mus_audio_device_name(dev))); line_in_use[line] = 1; end_sgi_print(); return(line);}int mus_audio_read(int line, char *buf, int bytes){ start_sgi_print();#ifdef AL_RESOURCE if (alReadFrames(port[line], (short *)buf, bytes / (channels[line] * datum_size[line])))#else if (ALreadsamps(port[line], (short *)buf, bytes / datum_size[line]))#endif RETURN_ERROR_EXIT(MUS_AUDIO_READ_ERROR, -1, "read error"); end_sgi_print(); return(MUS_NO_ERROR);}#ifdef AL_RESOURCE/* borrowed from /usr/share/src/dmedia/audio/printdevs.c with modifications */#define MAX_CHANNELS 8static float dB_to_linear(float val){ if (val == 0.0) return(1.0); return(pow(10.0, val / 20.0));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -