add support for playing IEEE float32 and float64 RIFF WAVE
samples on platforms that have these types natively, and can handle signed linear 32 bit samples. explicitly disabled on vax, run-or-compile-time sizeof() check disabled for everyone else now i can play a float32 .wav file i found. float64 not tested. copyright maint, update HISTORY, update audio drivers list.
This commit is contained in:
parent
7330f729cc
commit
95676db785
|
@ -1,7 +1,7 @@
|
||||||
/* $NetBSD: audio.c,v 1.25 2015/08/05 06:54:39 mrg Exp $ */
|
/* $NetBSD: audio.c,v 1.26 2019/11/09 12:46:44 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999 Matthew R. Green
|
* Copyright (c) 1999, 2013, 2015, 2019 Matthew R. Green
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: audio.c,v 1.25 2015/08/05 06:54:39 mrg Exp $");
|
__RCSID("$NetBSD: audio.c,v 1.26 2019/11/09 12:46:44 mrg Exp $");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,6 +110,8 @@ static const struct {
|
||||||
{ AudioEmpeg_l2_packets,AUDIO_ENCODING_MPEG_L2_PACKETS },
|
{ AudioEmpeg_l2_packets,AUDIO_ENCODING_MPEG_L2_PACKETS },
|
||||||
{ AudioEmpeg_l2_system, AUDIO_ENCODING_MPEG_L2_SYSTEM },
|
{ AudioEmpeg_l2_system, AUDIO_ENCODING_MPEG_L2_SYSTEM },
|
||||||
{ AudioEac3, AUDIO_ENCODING_AC3 },
|
{ AudioEac3, AUDIO_ENCODING_AC3 },
|
||||||
|
{ "ieee_float32", AUDIO_ENCODING_LIBAUDIO_FLOAT32 },
|
||||||
|
{ "ieee_float64", AUDIO_ENCODING_LIBAUDIO_FLOAT64 },
|
||||||
{ NULL, -1 }
|
{ NULL, -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* $NetBSD: libaudio.h,v 1.20 2015/08/05 06:54:39 mrg Exp $ */
|
/* $NetBSD: libaudio.h,v 1.21 2019/11/09 12:46:44 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2009 Matthew R. Green
|
* Copyright (c) 1999, 2009, 2013, 2015, 2019 Matthew R. Green
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -36,6 +36,17 @@
|
||||||
|
|
||||||
int audio_format_from_str (char *);
|
int audio_format_from_str (char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Audio encoding formats; this is a additional to those set
|
||||||
|
* in sys/audioio.h, but with a large offset to avoid future
|
||||||
|
* conflicts (additional ones are libaudio-software only.)
|
||||||
|
*
|
||||||
|
* This is to support floating-point WAV files. These require
|
||||||
|
* software conversion to a supported format.
|
||||||
|
*/
|
||||||
|
#define AUDIO_ENCODING_LIBAUDIO_FLOAT32 1001 /* 32-bit IEEE FP. */
|
||||||
|
#define AUDIO_ENCODING_LIBAUDIO_FLOAT64 1002 /* 64-bit IEEE FP. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We copy the Sun/NeXT on-disk audio header format and document what
|
* We copy the Sun/NeXT on-disk audio header format and document what
|
||||||
* we know of it here.
|
* we know of it here.
|
||||||
|
@ -107,10 +118,11 @@ int audio_encoding_to_sun (int, int, int *);
|
||||||
#define WAVAUDIO_FILE_MAGIC_FMT ((u_int32_t)0x666d7420)
|
#define WAVAUDIO_FILE_MAGIC_FMT ((u_int32_t)0x666d7420)
|
||||||
#define WAVAUDIO_FILE_MAGIC_DATA ((u_int32_t)0x64617461)
|
#define WAVAUDIO_FILE_MAGIC_DATA ((u_int32_t)0x64617461)
|
||||||
|
|
||||||
/* purloined from public Microsoft RIFF docs via sox or mplayer */
|
/* purloined from public Microsoft RIFF docs via sox, mplayer, or directly */
|
||||||
#define WAVE_FORMAT_UNKNOWN (0x0000)
|
#define WAVE_FORMAT_UNKNOWN (0x0000)
|
||||||
#define WAVE_FORMAT_PCM (0x0001)
|
#define WAVE_FORMAT_PCM (0x0001)
|
||||||
#define WAVE_FORMAT_ADPCM (0x0002)
|
#define WAVE_FORMAT_ADPCM (0x0002)
|
||||||
|
#define WAVE_FORMAT_IEEE_FLOAT (0x0003)
|
||||||
#define WAVE_FORMAT_ALAW (0x0006)
|
#define WAVE_FORMAT_ALAW (0x0006)
|
||||||
#define WAVE_FORMAT_MULAW (0x0007)
|
#define WAVE_FORMAT_MULAW (0x0007)
|
||||||
#define WAVE_FORMAT_OKI_ADPCM (0x0010)
|
#define WAVE_FORMAT_OKI_ADPCM (0x0010)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* $NetBSD: sun.c,v 1.9 2015/08/05 06:54:39 mrg Exp $ */
|
/* $NetBSD: sun.c,v 1.10 2019/11/09 12:46:44 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002 Matthew R. Green
|
* Copyright (c) 2002, 2013, 2015 Matthew R. Green
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: sun.c,v 1.9 2015/08/05 06:54:39 mrg Exp $");
|
__RCSID("$NetBSD: sun.c,v 1.10 2019/11/09 12:46:44 mrg Exp $");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* $NetBSD: wav.c,v 1.14 2017/11/25 17:18:15 jdolecek Exp $ */
|
/* $NetBSD: wav.c,v 1.15 2019/11/09 12:46:44 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2009 Matthew R. Green
|
* Copyright (c) 2002, 2009, 2013, 2015, 2019 Matthew R. Green
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: wav.c,v 1.14 2017/11/25 17:18:15 jdolecek Exp $");
|
__RCSID("$NetBSD: wav.c,v 1.15 2019/11/09 12:46:44 mrg Exp $");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ static const struct {
|
||||||
{ WAVE_FORMAT_UNKNOWN, "Microsoft Official Unknown" },
|
{ WAVE_FORMAT_UNKNOWN, "Microsoft Official Unknown" },
|
||||||
{ WAVE_FORMAT_PCM, "Microsoft PCM" },
|
{ WAVE_FORMAT_PCM, "Microsoft PCM" },
|
||||||
{ WAVE_FORMAT_ADPCM, "Microsoft ADPCM" },
|
{ WAVE_FORMAT_ADPCM, "Microsoft ADPCM" },
|
||||||
|
{ WAVE_FORMAT_IEEE_FLOAT,"Microsoft IEEE Floating-Point" },
|
||||||
{ WAVE_FORMAT_ALAW, "Microsoft A-law" },
|
{ WAVE_FORMAT_ALAW, "Microsoft A-law" },
|
||||||
{ WAVE_FORMAT_MULAW, "Microsoft mu-law" },
|
{ WAVE_FORMAT_MULAW, "Microsoft mu-law" },
|
||||||
{ WAVE_FORMAT_OKI_ADPCM,"OKI ADPCM" },
|
{ WAVE_FORMAT_OKI_ADPCM,"OKI ADPCM" },
|
||||||
|
@ -188,6 +189,20 @@ audio_wav_parse_hdr(void *hdr, size_t sz, u_int *enc, u_int *prec,
|
||||||
newenc = AUDIO_ENCODING_ULAW;
|
newenc = AUDIO_ENCODING_ULAW;
|
||||||
newprec = 8;
|
newprec = 8;
|
||||||
break;
|
break;
|
||||||
|
case WAVE_FORMAT_IEEE_FLOAT:
|
||||||
|
switch (getle16(fmt.bits_per_sample)) {
|
||||||
|
case 32:
|
||||||
|
newenc = AUDIO_ENCODING_LIBAUDIO_FLOAT32;
|
||||||
|
newprec = 32;
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
newenc = AUDIO_ENCODING_LIBAUDIO_FLOAT64;
|
||||||
|
newprec = 32;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (AUDIO_EWAVBADPCM);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.\" $NetBSD: audioplay.1,v 1.26 2014/03/18 18:20:44 riastradh Exp $
|
.\" $NetBSD: audioplay.1,v 1.27 2019/11/09 12:46:44 mrg Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 1998, 1999, 2002, 2010 Matthew R. Green
|
.\" Copyright (c) 1998, 1999, 2002, 2010, 2019 Matthew R. Green
|
||||||
.\" All rights reserved.
|
.\" All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
.\" Redistribution and use in source and binary forms, with or without
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd December 30, 2010
|
.Dd November 8, 2019
|
||||||
.Dt AUDIOPLAY 1
|
.Dt AUDIOPLAY 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -172,6 +172,15 @@ can be used to play Sun/NeXT audio files, and also RIFF WAVE audio files.
|
||||||
can be configured in the
|
can be configured in the
|
||||||
.Dq Netscape
|
.Dq Netscape
|
||||||
web browser as the program to use when playing audio files.
|
web browser as the program to use when playing audio files.
|
||||||
|
.Pp
|
||||||
|
In addition to the audio driver encodings list in the EXAMPLES section,
|
||||||
|
.Nm
|
||||||
|
supports playing IEEE floating point data in RIFF WAVE audio files
|
||||||
|
(with one caveat that the flaoting point size must be native.)
|
||||||
|
In this case
|
||||||
|
.Nm
|
||||||
|
converts the floating point data into signed linear samples before
|
||||||
|
they are passed to the chosen audio device.
|
||||||
.Sh ERRORS
|
.Sh ERRORS
|
||||||
If the audio device or the control device can not be opened, and error is
|
If the audio device or the control device can not be opened, and error is
|
||||||
returned.
|
returned.
|
||||||
|
@ -182,29 +191,55 @@ hardware driver.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr audioctl 1 ,
|
.Xr audioctl 1 ,
|
||||||
.Xr audiorecord 1 ,
|
.Xr audiorecord 1 ,
|
||||||
|
.Xr aica 4 ,
|
||||||
|
.Xr arcofi 4 ,
|
||||||
.Xr aria 4 ,
|
.Xr aria 4 ,
|
||||||
.Xr audio 4 ,
|
.Xr audio 4 ,
|
||||||
.Xr audioamd 4 ,
|
.Xr audioamd 4 ,
|
||||||
.Xr auich 4 ,
|
.Xr auich 4 ,
|
||||||
|
.Xr auixp 4 ,
|
||||||
|
.Xr ausoc 4 ,
|
||||||
.Xr autri 4 ,
|
.Xr autri 4 ,
|
||||||
.Xr auvia 4 ,
|
.Xr auvia 4 ,
|
||||||
|
.Xr awacs 4 ,
|
||||||
|
.Xr bba 4 ,
|
||||||
|
.Xr btsco 4 ,
|
||||||
.Xr clcs 4 ,
|
.Xr clcs 4 ,
|
||||||
.Xr clct 4 ,
|
.Xr clct 4 ,
|
||||||
.Xr cmpci 4 ,
|
.Xr cmpci 4 ,
|
||||||
|
.Xr dbri 4 ,
|
||||||
.Xr eap 4 ,
|
.Xr eap 4 ,
|
||||||
.Xr emuxki 4 ,
|
.Xr emuxki 4 ,
|
||||||
.Xr esm 4 ,
|
.Xr esm 4 ,
|
||||||
.Xr eso 4 ,
|
.Xr eso 4 ,
|
||||||
.Xr ess 4 ,
|
.Xr ess 4 ,
|
||||||
.Xr fms 4 ,
|
.Xr fms 4 ,
|
||||||
|
.Xr gcscaudio 4 ,
|
||||||
.Xr gus 4 ,
|
.Xr gus 4 ,
|
||||||
.Xr guspnp 4 ,
|
.Xr guspnp 4 ,
|
||||||
|
.Xr haltwo 4 ,
|
||||||
|
.Xr harmony 4 ,
|
||||||
|
.Xr hdafg 4 ,
|
||||||
|
.Xr mavb 4 ,
|
||||||
.Xr neo 4 ,
|
.Xr neo 4 ,
|
||||||
|
.Xr pad 4 ,
|
||||||
|
.Xr pas 4 ,
|
||||||
|
.Xr paud 4 ,
|
||||||
|
.Xr repluse 4 ,
|
||||||
.Xr sb 4 ,
|
.Xr sb 4 ,
|
||||||
|
.Xr snapper 4 ,
|
||||||
.Xr sv 4 ,
|
.Xr sv 4 ,
|
||||||
|
.Xr toccata 4 ,
|
||||||
|
.Xr uaudio 4 ,
|
||||||
|
.Xr vaudio 4 ,
|
||||||
|
.Xr vcaudio 4 ,
|
||||||
|
.Xr vraiu 4 ,
|
||||||
|
.Xr vs 4 ,
|
||||||
|
.Xr vsaudio 4 ,
|
||||||
.Xr wss 4 ,
|
.Xr wss 4 ,
|
||||||
.Xr yds 4 ,
|
.Xr yds 4 ,
|
||||||
.Xr ym 4
|
.Xr ym 4 ,
|
||||||
|
.Xr zaudio 4
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -214,6 +249,10 @@ The
|
||||||
.Nm
|
.Nm
|
||||||
was first made available in
|
was first made available in
|
||||||
.Nx 1.4 .
|
.Nx 1.4 .
|
||||||
|
Support for RIFF WAVE recording was introduced in
|
||||||
|
.Nx 1.6 .
|
||||||
|
Support for RIFF WAVE IEEE floating point data was introduced in
|
||||||
|
.Nx 10.0 .
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: play.c,v 1.57 2019/05/04 08:27:30 isaki Exp $ */
|
/* $NetBSD: play.c,v 1.58 2019/11/09 12:46:44 mrg Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2000, 2001, 2002, 2010 Matthew R. Green
|
* Copyright (c) 1999, 2000, 2001, 2002, 2010 Matthew R. Green
|
||||||
|
@ -28,10 +28,9 @@
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: play.c,v 1.57 2019/05/04 08:27:30 isaki Exp $");
|
__RCSID("$NetBSD: play.c,v 1.58 2019/11/09 12:46:44 mrg Exp $");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/audioio.h>
|
#include <sys/audioio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
@ -51,10 +50,14 @@ __RCSID("$NetBSD: play.c,v 1.57 2019/05/04 08:27:30 isaki Exp $");
|
||||||
|
|
||||||
#include "libaudio.h"
|
#include "libaudio.h"
|
||||||
|
|
||||||
|
typedef size_t (*convert)(void *inbuf, void *outbuf, size_t len);
|
||||||
|
|
||||||
static void usage(void) __dead;
|
static void usage(void) __dead;
|
||||||
static void play(char *);
|
static void play(char *);
|
||||||
static void play_fd(const char *, int);
|
static void play_fd(const char *, int);
|
||||||
static ssize_t audioctl_write_fromhdr(void *, size_t, int, off_t *, const char *);
|
static ssize_t audioctl_write_fromhdr(void *, size_t, int,
|
||||||
|
off_t *, const char *,
|
||||||
|
convert *);
|
||||||
static void cleanup(int) __dead;
|
static void cleanup(int) __dead;
|
||||||
|
|
||||||
static audio_info_t info;
|
static audio_info_t info;
|
||||||
|
@ -214,9 +217,90 @@ cleanup(int signo)
|
||||||
exit(exitstatus);
|
exit(exitstatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __vax__
|
||||||
|
static size_t
|
||||||
|
float32_to_linear32(void *inbuf, void *outbuf, size_t len)
|
||||||
|
{
|
||||||
|
uint8_t *inbuf8 = inbuf, *end = inbuf8 + len;
|
||||||
|
uint8_t *outbuf8 = outbuf;
|
||||||
|
float f;
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
while (inbuf8 + sizeof f <= end) {
|
||||||
|
memcpy(&f, inbuf8, sizeof f);
|
||||||
|
|
||||||
|
/* saturate */
|
||||||
|
if (f < -1.0)
|
||||||
|
f = -1.0;
|
||||||
|
if (f > 1.0)
|
||||||
|
f = 1.0;
|
||||||
|
|
||||||
|
/* Convert -1.0 to +1.0 into a 32 bit signed value */
|
||||||
|
i = f * ((1u << 31) - 1);
|
||||||
|
|
||||||
|
memcpy(outbuf8, &i, sizeof i);
|
||||||
|
|
||||||
|
inbuf8 += sizeof f;
|
||||||
|
outbuf8 += sizeof i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
float64_to_linear32(void *inbuf, void *outbuf, size_t len)
|
||||||
|
{
|
||||||
|
uint8_t *inbuf8 = inbuf, *end = inbuf8 + len;
|
||||||
|
uint8_t *outbuf8 = outbuf;
|
||||||
|
double f;
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
while (inbuf8 + sizeof f <= end) {
|
||||||
|
memcpy(&f, inbuf8, sizeof f);
|
||||||
|
|
||||||
|
/* saturate */
|
||||||
|
if (f < -1.0)
|
||||||
|
f = -1.0;
|
||||||
|
if (f > 1.0)
|
||||||
|
f = 1.0;
|
||||||
|
|
||||||
|
/* Convert -1.0 to +1.0 into a 32 bit signed value */
|
||||||
|
i = f * ((1u << 31) - 1);
|
||||||
|
|
||||||
|
memcpy(outbuf8, &i, sizeof i);
|
||||||
|
|
||||||
|
inbuf8 += sizeof f;
|
||||||
|
outbuf8 += sizeof i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len / 2;
|
||||||
|
}
|
||||||
|
#endif /* __vax__ */
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
audio_write(int fd, void *buf, size_t len, convert conv)
|
||||||
|
{
|
||||||
|
static void *convert_buffer;
|
||||||
|
static size_t convert_buffer_size;
|
||||||
|
|
||||||
|
if (conv == NULL)
|
||||||
|
return write(fd, buf, len);
|
||||||
|
|
||||||
|
if (convert_buffer == NULL || convert_buffer_size < len) {
|
||||||
|
free(convert_buffer);
|
||||||
|
convert_buffer = malloc(len);
|
||||||
|
if (convert_buffer == NULL)
|
||||||
|
err(1, "malloc of convert buffer failed");
|
||||||
|
convert_buffer_size = len;
|
||||||
|
}
|
||||||
|
len = conv(buf, convert_buffer, len);
|
||||||
|
return write(fd, convert_buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
play(char *file)
|
play(char *file)
|
||||||
{
|
{
|
||||||
|
convert conv = NULL;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
void *addr, *oaddr;
|
void *addr, *oaddr;
|
||||||
off_t filesize;
|
off_t filesize;
|
||||||
|
@ -265,10 +349,11 @@ play(char *file)
|
||||||
madvise(addr, sizet_filesize, MADV_SEQUENTIAL);
|
madvise(addr, sizet_filesize, MADV_SEQUENTIAL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get the header length and set up the audio device
|
* get the header length and set up the audio device, and
|
||||||
|
* determine any conversion needed.
|
||||||
*/
|
*/
|
||||||
if ((hdrlen = audioctl_write_fromhdr(addr,
|
if ((hdrlen = audioctl_write_fromhdr(addr,
|
||||||
sizet_filesize, audiofd, &datasize, file)) < 0) {
|
sizet_filesize, audiofd, &datasize, file, &conv)) < 0) {
|
||||||
if (play_errstring)
|
if (play_errstring)
|
||||||
errx(1, "%s: %s", play_errstring, file);
|
errx(1, "%s: %s", play_errstring, file);
|
||||||
else
|
else
|
||||||
|
@ -284,7 +369,7 @@ play(char *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((uint64_t)datasize > bufsize) {
|
while ((uint64_t)datasize > bufsize) {
|
||||||
nw = write(audiofd, addr, bufsize);
|
nw = audio_write(audiofd, addr, bufsize, conv);
|
||||||
if (nw == -1)
|
if (nw == -1)
|
||||||
err(1, "write failed");
|
err(1, "write failed");
|
||||||
if ((size_t)nw != bufsize)
|
if ((size_t)nw != bufsize)
|
||||||
|
@ -292,7 +377,7 @@ play(char *file)
|
||||||
addr = (char *)addr + bufsize;
|
addr = (char *)addr + bufsize;
|
||||||
datasize -= bufsize;
|
datasize -= bufsize;
|
||||||
}
|
}
|
||||||
nw = write(audiofd, addr, datasize);
|
nw = audio_write(audiofd, addr, datasize, conv);
|
||||||
if (nw == -1)
|
if (nw == -1)
|
||||||
err(1, "final write failed");
|
err(1, "final write failed");
|
||||||
if ((off_t)nw != datasize)
|
if ((off_t)nw != datasize)
|
||||||
|
@ -312,6 +397,7 @@ play(char *file)
|
||||||
static void
|
static void
|
||||||
play_fd(const char *file, int fd)
|
play_fd(const char *file, int fd)
|
||||||
{
|
{
|
||||||
|
convert conv = NULL;
|
||||||
char *buffer = malloc(bufsize);
|
char *buffer = malloc(bufsize);
|
||||||
ssize_t hdrlen;
|
ssize_t hdrlen;
|
||||||
int nr, nw;
|
int nr, nw;
|
||||||
|
@ -331,7 +417,7 @@ play_fd(const char *file, int fd)
|
||||||
}
|
}
|
||||||
err(1, "unexpected EOF");
|
err(1, "unexpected EOF");
|
||||||
}
|
}
|
||||||
hdrlen = audioctl_write_fromhdr(buffer, nr, audiofd, &datasize, file);
|
hdrlen = audioctl_write_fromhdr(buffer, nr, audiofd, &datasize, file, &conv);
|
||||||
if (hdrlen < 0) {
|
if (hdrlen < 0) {
|
||||||
if (play_errstring)
|
if (play_errstring)
|
||||||
errx(1, "%s: %s", play_errstring, file);
|
errx(1, "%s: %s", play_errstring, file);
|
||||||
|
@ -347,7 +433,7 @@ play_fd(const char *file, int fd)
|
||||||
while (datasize == 0 || dataout < datasize) {
|
while (datasize == 0 || dataout < datasize) {
|
||||||
if (datasize != 0 && dataout + nr > datasize)
|
if (datasize != 0 && dataout + nr > datasize)
|
||||||
nr = datasize - dataout;
|
nr = datasize - dataout;
|
||||||
nw = write(audiofd, buffer, nr);
|
nw = audio_write(audiofd, buffer, nr, conv);
|
||||||
if (nw == -1)
|
if (nw == -1)
|
||||||
err(1, "audio device write failed");
|
err(1, "audio device write failed");
|
||||||
if (nw != nr)
|
if (nw != nr)
|
||||||
|
@ -374,11 +460,13 @@ read_error:
|
||||||
* uses the local "info" variable. blah... fix me!
|
* uses the local "info" variable. blah... fix me!
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
static ssize_t
|
||||||
audioctl_write_fromhdr(void *hdr, size_t fsz, int fd, off_t *datasize, const char *file)
|
audioctl_write_fromhdr(void *hdr, size_t fsz, int fd, off_t *datasize, const char *file, convert *conv)
|
||||||
{
|
{
|
||||||
sun_audioheader *sunhdr;
|
sun_audioheader *sunhdr;
|
||||||
ssize_t hdr_len = 0;
|
ssize_t hdr_len = 0;
|
||||||
|
|
||||||
|
*conv = NULL;
|
||||||
|
|
||||||
AUDIO_INITINFO(&info);
|
AUDIO_INITINFO(&info);
|
||||||
sunhdr = hdr;
|
sunhdr = hdr;
|
||||||
if (ntohl(sunhdr->magic) == AUDIO_FILE_MAGIC) {
|
if (ntohl(sunhdr->magic) == AUDIO_FILE_MAGIC) {
|
||||||
|
@ -457,6 +545,32 @@ set_audio_mode:
|
||||||
enc ? enc : "");
|
enc ? enc : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __vax__
|
||||||
|
if (info.play.encoding == AUDIO_ENCODING_LIBAUDIO_FLOAT32 ||
|
||||||
|
info.play.encoding == AUDIO_ENCODING_LIBAUDIO_FLOAT64) {
|
||||||
|
const char *msg;
|
||||||
|
|
||||||
|
if (info.play.encoding == AUDIO_ENCODING_LIBAUDIO_FLOAT32) {
|
||||||
|
if (sizeof(float) * CHAR_BIT != 32)
|
||||||
|
return -1;
|
||||||
|
*conv = float32_to_linear32;
|
||||||
|
msg = "32";
|
||||||
|
} else {
|
||||||
|
if (sizeof(double) * CHAR_BIT != 64)
|
||||||
|
return -1;
|
||||||
|
*conv = float64_to_linear32;
|
||||||
|
msg = "32";
|
||||||
|
}
|
||||||
|
info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
|
||||||
|
info.play.precision = 32;
|
||||||
|
if (verbose)
|
||||||
|
printf("%s: converting IEEE float%s to precision=%d "
|
||||||
|
"encoding=%s\n", file, msg,
|
||||||
|
info.play.precision,
|
||||||
|
audio_enc_from_val(info.play.encoding));
|
||||||
|
}
|
||||||
|
#endif /* __vax__ */
|
||||||
|
|
||||||
if (ioctl(fd, AUDIO_SETINFO, &info) < 0)
|
if (ioctl(fd, AUDIO_SETINFO, &info) < 0)
|
||||||
err(1, "failed to set audio info");
|
err(1, "failed to set audio info");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue