audio_hpold.c
来自「speech signal process tools」· C语言 代码 · 共 902 行 · 第 1/2 页
C
902 行
/* * This material contains unpublished, proprietary software of Entropic * Research Laboratory, Inc. Any reproduction, distribution, or publication * of this work must be authorized in writing by Entropic Research * Laboratory, Inc., and must bear the notice: * * "Copyright (c) 1995 Entropic Research Laboratory, Inc. All rights reserved" * * The copyright notice above does not evidence any actual or intended * publication of this source code. * * Written by: Checked by: Revised by: * * Brief description: * */static char *sccs_id = "%W% %G% ERL";#include <stdio.h>#include <math.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <netinet/in.h>#include <audio/Alib.h>#include <sys/time.h>#include <sys/types.h>#include <errno.h>#include <unistd.h>#include <sys/param.h>/* * --------------------------------------------------------------- * Machine-dependent declaration * --------------------------------------------------------------- */static int *sampleRates = NULL;static AGainDB maxIn;static AGainDB minIn;static AGainDB maxOut;static AGainDB minOut;static Audio *audio = NULL;static int sizeof_sample;static AInputChMask InputChannelsSupported;/* record */static AudioAttrMask recordAttribsMask;static AudioAttributes recordAttribs;static SSRecordParams recordStreamParams;static SStream recordStream;static ATransID recordXid;static int recordSocket = -1;static int recordGainR, recordGainL;static AGainEntry recordGainEntry[4];static int recordDestSet = 0;static int recordGainSet = 0;static double recordRate;static int recordChannel;static int recordNSampsPerChan;static recordInitCalled = 0;/* play */static AudioAttrMask playSrcAttribsMask;static AudioAttrMask playAttribsMask;static AudioAttributes playSrcAttribs;static AudioAttributes playAttribs;static SSPlayParams playStreamParams;static SStream playStream;static ATransID playXid = NULL;static int playSocket = -1;/* <0 when audio is in close state */#ifndef WRITEstatic FILE *playFP = NULL;#endifstatic int playChan = 1;static int playPortBufSize;static int fileRate;static unsigned long playSamps = 0;static long playPauseCount = 0;static int playPause = 0;static struct timeval playBgnTime;static AGainEntry playGainEntry[4];static int playGainSet = 0;static int playGainR, playGainL;static int playDrain = 0;static double playRate;static int playNSampsPerChan;static int playInitCalled = 0;static int useIntSpeaker = 0;static AErrorHandler prevHandler;#ifdef WRITE_TESTstatic FILE * test_fp = NULL;#endifstatic int first_write=0;char audio_error_msg[512];#define perror private_perrorextern int sys_nerr;extern char *sys_errlist[];int closest_srate();static voidprivate_perror(s) char *s;{ if (errno < sys_nerr) sprintf(audio_error_msg, "%s: %s\n", s, sys_errlist[errno]); else sprintf(audio_error_msg, "%s: Unknown ioctl error\n", s);}static longErrorHandler(audio, err_event) Audio *audio; AErrorEvent *err_event;{ char errorbuff[132]; AGetErrorText(audio, err_event->error_code, errorbuff, 131); fprintf(stderr, "HP Audio Error: %s\n", errorbuff); return 0;}#define PLAYHOLD 300000static intGetFilled(fd) int fd;{ int canread; if (ioctl(fd, FIONREAD, &canread) < 0) { perror("error in GetFilled"); return (0); } return canread / sizeof_sample;}intPortIsAvailable(){ long status; char server[MAXHOSTNAMELEN], *s = NULL; unsigned long *srates; long nRates, i; if (audio) return 0; s = getenv("AUDIO"); if (s) strcpy(server, s); else strcpy(server, ":0"); prevHandler = ASetErrorHandler(ErrorHandler); audio = AOpenAudio(server, &status); if (status) { sprintf(audio_error_msg, "Trouble opening audio, error code: %ld\n", status); return (1); } nRates = ANumSamplingRates(audio); if (!nRates) { sprintf(audio_error_msg, "Trouble opening audio, ANumSamplingRates returns 0.\n"); return 1; } srates = ASamplingRates(audio); if (sampleRates) free(sampleRates); sampleRates = (int *) malloc(sizeof(int) * (nRates + 1)); sampleRates[nRates] = 0; for (i = 0; i < nRates; i++) sampleRates[i] = srates[i]; maxIn = AMaxInputGain(audio); maxOut = AMaxOutputGain(audio); minIn = AMinInputGain(audio); minOut = AMinOutputGain(audio); InputChannelsSupported = AInputChannels(audio); return (0);}/* * ----------------------------------------------------------------- Record * ----------------------------------------------------------------- */intAudioMaxChannels(){ /* * InputChannelsSupported is a bit mask that represents the available A/D * input channels on the hardware. Here we use that fact that mono * capabilities is numerically equal to 1 and that the upper limit is two * channels. */ if ((InputChannelsSupported & AMonoInputChMask) && !(InputChannelsSupported & ALeftInputChMask) && !(InputChannelsSupported & ARightInputChMask)) return 1; else if ((InputChannelsSupported & ALeftInputChMask) && (InputChannelsSupported & ARightInputChMask)) return 2; else return 0;}int *AudioGetRates(){ return (sampleRates);}intInitAudioRecord(srate, channel, nSampsPerChan) double srate; int channel; int nSampsPerChan;{ long status; if (PortIsAvailable()) { (void) sprintf(audio_error_msg, "Sorry, this record program requires hp700 audio.\n"); return (1); } recordChannel = channel; recordNSampsPerChan = nSampsPerChan; sizeof_sample = sizeof(short); /* Set the sample rate. */ recordAttribs = *ABestAudioAttributes(audio); recordRate = recordAttribs.attr.sampled_attr.sampling_rate = closest_srate(srate, sampleRates); /* * HP's audio server has a bufer of limited audio->block_size size. At * least on HP700, this is 4096 (N) bytes. Number of data points * transferred must not exceed N bytes in every consecutive read; * otherwise, overflow occurs, unread data gets overwritten in the buffer. * The result is samples lost during recording. Here I use a rule of data * transfered every some sec must not exceed N bytes (enough so that * single channel 48 Hz is recordable) */ if (0.08 * srate * channel * sizeof_sample > audio->block_size) { sprintf(audio_error_msg, "InitAudioRecord: Sampling rate too high or too many channels specified.\n"); ACloseAudio(audio, NULL); return (1); } /* Set up defaults in the HP audio attrib structure */ recordAttribsMask = 0; recordAttribsMask = (recordAttribsMask | ASSamplingRateMask | ASChannelsMask | ASDataFormatMask); recordAttribs.attr.sampled_attr.channels = (channel < 2) ? 1 : 2; recordAttribs.attr.sampled_attr.data_format = ADFLin16; recordAttribs.attr.sampled_attr.bits_per_sample = 16; switch (recordAttribs.attr.sampled_attr.channels) { case 1: recordGainEntry[0].u.i.in_ch = AICTMono; recordGainEntry[0].gain = AUnityGain; break; case 2: default: recordGainEntry[0].u.i.in_ch = AICTLeft; recordGainEntry[1].u.i.in_ch = AICTRight; recordGainEntry[0].gain = AUnityGain; recordGainEntry[1].gain = AUnityGain; break; } recordStreamParams.event_mask = 0; recordStreamParams.gain_matrix.type = AGMTInput; recordStreamParams.gain_matrix.num_entries = recordAttribs.attr.sampled_attr.channels; recordStreamParams.gain_matrix.gain_entries = recordGainEntry; recordXid = ARecordSStream(audio, ~0, &recordAttribs, &recordStreamParams, &recordStream, &status); if (status) { sprintf(audio_error_msg, "InitAudioRecord: can't open audio stream, code %ld.\n", status); ACloseAudio(audio, NULL); return 1; } recordInitCalled = 1; return (0);}intCloseAudioRecord(){ long status; if (recordSocket < 0) return (0); close(recordSocket); recordSocket = -1; recordInitCalled = 0; ACloseAudio(audio, &status); audio = NULL; return (status);}intPauseAudioRecord(){ (void) CloseAudioRecord(); return (0);}intStartAudioRecord(){ long status; recordXid = ARecordSStream(audio, ~0, &recordAttribs, &recordStreamParams, &recordStream, &status); if (status) { sprintf(audio_error_msg, "StartAudioRecord: can't open audio stream, code %ld.\n", status); (void) ACloseAudio(audio, NULL); return 1; } recordSocket = socket(AF_INET, SOCK_STREAM, 0); if (recordSocket < 0) { perror("StartAudioRecord: Socket creation failed"); return 1; } status = connect(recordSocket, (struct sockaddr *) & recordStream.tcp_sockaddr, sizeof(struct sockaddr_in)); if (status < 0) { perror("StartAudioRecord: Connect failed"); return (1); } if (recordGainSet) { switch (recordAttribs.attr.sampled_attr.channels) { case 1: ASetChannelGain(audio, recordXid, ACTMono, recordGainL, &status); if (status) { sprintf(audio_error_msg, "StartAudioRecord: can't set channel gain, code %ld.\n", status); (void) ACloseAudio(audio, NULL); return 1; } break; case 2: default: ASetChannelGain(audio, recordXid, ACTLeft, recordGainL, &status); ASetChannelGain(audio, recordXid, ACTRight, recordGainR, &status); if (status) { sprintf(audio_error_msg, "StartAudioRecord: can't set channel gain, code %ld.\n", status); (void) ACloseAudio(audio, NULL); return 1; } break; } } return (0);}intContAudioRecord(){ int status; status = InitAudioRecord(recordRate, recordChannel, recordNSampsPerChan); if (status) return 1; status = StartAudioRecord(); if (status) return 1; return (0);}/* * in case of STEREO recording, RecordAudio returns total number of samples * in both channels */intRecordAudio(inputBuffer) short *inputBuffer;{ int canread, haveread = 0; /* * Sigh, can't find a way to reliably check for overflow condition. That * is why a precaution check is installed in InitAudioRecord */ canread = GetFilled(recordSocket); if (canread) haveread = read(recordSocket, inputBuffer, canread * sizeof_sample) / sizeof_sample; return (haveread);}intSetAudioInputType(src) char *src;{ int useLineIn = 0; if (!strcmp(src, "mic")) useLineIn = 0; else useLineIn = 1; /* * Because InitAudioRecord must be called first to know how many channel * we have, We can't set gainEntry which setting is channel dependent * before the device is open. */ if (recordInitCalled) { /* * close up the connection and restart. Unfortunately HP won't let you * change output destination while device is open. */ (void) CloseAudioRecord(); switch (recordAttribs.attr.sampled_attr.channels) { case 1: recordGainEntry[0].u.i.in_ch = AICTMono; recordGainEntry[0].u.i.in_src = (useLineIn) ? AISTMonoAuxiliary : AISTMonoMicrophone; break; case 2: default: recordGainEntry[0].u.i.in_ch = AICTLeft; recordGainEntry[0].u.i.in_src = (useLineIn) ? AISTLeftAuxiliary : AISTLeftMicrophone; recordGainEntry[1].u.i.in_ch = AICTRight; recordGainEntry[1].u.i.in_src = (useLineIn) ? AISTRightAuxiliary : AISTRightMicrophone; break; } recordDestSet = 1; InitAudioRecord(recordRate, recordChannel, recordNSampsPerChan); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?