blob: 09403886b82c6bd1d7eb675d0cd3fd3af1d4e176 [file] [log] [blame] [edit]
/*
* BRLTTY - A background process providing access to the console screen (when in
* text mode) for a blind person using a refreshable braille display.
*
* Copyright (C) 1995-2023 by The BRLTTY Developers.
*
* BRLTTY comes with ABSOLUTELY NO WARRANTY.
*
* This is free software, placed under the terms of the
* GNU Lesser General Public License, as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any
* later version. Please see the file LICENSE-LGPL for details.
*
* Web Page: http://brltty.app/
*
* This software is maintained by Dave Mielke <dave@mielke.cc>.
*/
#include "prologue.h"
#ifdef HAVE_HPUX_AUDIO
#include <Alib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif /* HAVE_HPUX_AUDIO */
#include "log.h"
#include "pcm.h"
#ifdef HAVE_HPUX_AUDIO
static Audio *audioServer = NULL;
struct PcmDeviceStruct {
ATransID transaction;
SStream stream;
int socket;
};
static void
logAudioError (int level, long status, const char *action) {
char message[132];
AGetErrorText(audioServer, status, message, sizeof(message)-1);
logMessage(level, "%s error %ld: %s", action, status, message);
}
static const AudioAttributes *
getAudioAttributes (PcmDevice *pcm) {
return &pcm->stream.audio_attr;
}
#endif /* HAVE_HPUX_AUDIO */
PcmDevice *
openPcmDevice (int errorLevel, const char *device) {
#ifdef HAVE_HPUX_AUDIO
PcmDevice *pcm;
if ((pcm = malloc(sizeof(*pcm)))) {
long status;
AudioAttrMask mask = 0;
AudioAttributes attributes;
SSPlayParams parameters;
if (!audioServer) {
char *server = "";
audioServer = AOpenAudio(server, &status);
if (status != AENoError) {
logAudioError(errorLevel, status, "AOpenAudio");
audioServer = NULL;
goto noServer;
}
logMessage(LOG_DEBUG, "connected to audio server: %s", AAudioString(audioServer));
ASetCloseDownMode(audioServer, AKeepTransactions, &status);
if (status != AENoError) {
logAudioError(errorLevel, status, "ASetCloseDownMode");
}
}
memset(&attributes, 0, sizeof(attributes));
parameters.gain_matrix = *ASimplePlayer(audioServer);
parameters.play_volume = AUnityGain;
parameters.priority = APriorityUrgent;
parameters.event_mask = 0;
pcm->transaction = APlaySStream(audioServer, mask, &attributes, &parameters, &pcm->stream, &status);
if (status == AENoError) {
if ((pcm->socket = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
if (connect(pcm->socket, (struct sockaddr *)&pcm->stream.tcp_sockaddr, sizeof(pcm->stream.tcp_sockaddr)) != -1) {
return pcm;
} else {
logSystemError("PCM socket connection");
}
close(pcm->socket);
} else {
logSystemError("PCM socket creation");
}
} else {
logAudioError(errorLevel, status, "APlaySStream");
}
noServer:
free(pcm);
} else {
logSystemError("PCM device allocation");
}
#endif /* HAVE_HPUX_AUDIO */
return NULL;
}
void
closePcmDevice (PcmDevice *pcm) {
close(pcm->socket);
free(pcm);
}
int
writePcmData (PcmDevice *pcm, const unsigned char *buffer, int count) {
return safe_write(pcm->socket, buffer, count) != -1;
}
int
getPcmBlockSize (PcmDevice *pcm) {
int size = 0X100;
#ifdef HAVE_HPUX_AUDIO
size = MIN(size, pcm->stream.max_block_size);
#endif /* HAVE_HPUX_AUDIO */
return size;
}
int
getPcmSampleRate (PcmDevice *pcm) {
#ifdef HAVE_HPUX_AUDIO
return getAudioAttributes(pcm)->attr.sampled_attr.sampling_rate;
#else /* HAVE_HPUX_AUDIO */
return 8000;
#endif /* HAVE_HPUX_AUDIO */
}
int
setPcmSampleRate (PcmDevice *pcm, int rate) {
return getPcmSampleRate(pcm);
}
int
getPcmChannelCount (PcmDevice *pcm) {
#ifdef HAVE_HPUX_AUDIO
return getAudioAttributes(pcm)->attr.sampled_attr.channels;
#else /* HAVE_HPUX_AUDIO */
return 1;
#endif /* HAVE_HPUX_AUDIO */
}
int
setPcmChannelCount (PcmDevice *pcm, int channels) {
return getPcmChannelCount(pcm);
}
PcmAmplitudeFormat
getPcmAmplitudeFormat (PcmDevice *pcm) {
#ifdef HAVE_HPUX_AUDIO
switch (getAudioAttributes(pcm)->attr.sampled_attr.data_format) {
default:
break;
case ADFLin8:
return PCM_FMT_S8;
case ADFLin8Offset:
return PCM_FMT_U8;
case ADFLin16:
return PCM_FMT_S16B;
case ADFMuLaw:
return PCM_FMT_ULAW;
}
#endif /* HAVE_HPUX_AUDIO */
return PCM_FMT_UNKNOWN;
}
PcmAmplitudeFormat
setPcmAmplitudeFormat (PcmDevice *pcm, PcmAmplitudeFormat format) {
return getPcmAmplitudeFormat(pcm);
}
void
pushPcmOutput (PcmDevice *pcm) {
}
void
awaitPcmOutput (PcmDevice *pcm) {
}
void
cancelPcmOutput (PcmDevice *pcm) {
}