Home | History | Annotate | Line # | Download | only in common
      1  1.11      gson /*	$NetBSD: sun.c,v 1.11 2024/02/27 21:05:34 gson Exp $	*/
      2   1.1       mrg 
      3   1.1       mrg /*
      4  1.10       mrg  * Copyright (c) 2002, 2013, 2015 Matthew R. Green
      5   1.1       mrg  * All rights reserved.
      6   1.1       mrg  *
      7   1.1       mrg  * Redistribution and use in source and binary forms, with or without
      8   1.1       mrg  * modification, are permitted provided that the following conditions
      9   1.1       mrg  * are met:
     10   1.1       mrg  * 1. Redistributions of source code must retain the above copyright
     11   1.1       mrg  *    notice, this list of conditions and the following disclaimer.
     12   1.1       mrg  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1       mrg  *    notice, this list of conditions and the following disclaimer in the
     14   1.1       mrg  *    documentation and/or other materials provided with the distribution.
     15   1.1       mrg  *
     16   1.1       mrg  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17   1.1       mrg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18   1.1       mrg  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19   1.1       mrg  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20   1.1       mrg  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21   1.1       mrg  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22   1.1       mrg  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23   1.1       mrg  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24   1.1       mrg  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25   1.1       mrg  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26   1.1       mrg  * SUCH DAMAGE.
     27   1.1       mrg  */
     28   1.1       mrg 
     29   1.1       mrg /*
     30   1.1       mrg  * XXX this is slightly icky in places...
     31   1.1       mrg  */
     32   1.3       agc #include <sys/cdefs.h>
     33   1.3       agc 
     34   1.3       agc #ifndef lint
     35  1.11      gson __RCSID("$NetBSD: sun.c,v 1.11 2024/02/27 21:05:34 gson Exp $");
     36   1.3       agc #endif
     37   1.3       agc 
     38   1.1       mrg 
     39   1.1       mrg #include <sys/types.h>
     40   1.1       mrg #include <sys/audioio.h>
     41   1.1       mrg #include <sys/ioctl.h>
     42   1.1       mrg #include <sys/time.h>
     43   1.1       mrg 
     44   1.1       mrg #include <ctype.h>
     45   1.1       mrg #include <err.h>
     46   1.1       mrg #include <stdio.h>
     47   1.1       mrg #include <stdlib.h>
     48   1.1       mrg #include <string.h>
     49   1.8       mrg #include <unistd.h>
     50   1.1       mrg 
     51   1.1       mrg #include "libaudio.h"
     52   1.8       mrg #include "auconv.h"
     53   1.1       mrg 
     54   1.1       mrg /*
     55   1.1       mrg  * SunOS/NeXT .au format helpers
     56   1.1       mrg  */
     57   1.7     joerg static const struct {
     58   1.1       mrg 	int	file_encoding;
     59   1.1       mrg 	int	encoding;
     60   1.1       mrg 	int	precision;
     61   1.1       mrg } file2sw_encodings[] = {
     62   1.1       mrg 	{ AUDIO_FILE_ENCODING_MULAW_8,		AUDIO_ENCODING_ULAW,	8 },
     63   1.2       mrg 	{ AUDIO_FILE_ENCODING_LINEAR_8,		AUDIO_ENCODING_SLINEAR_BE, 8 },
     64   1.2       mrg 	{ AUDIO_FILE_ENCODING_LINEAR_16,	AUDIO_ENCODING_SLINEAR_BE, 16 },
     65   1.2       mrg 	{ AUDIO_FILE_ENCODING_LINEAR_24,	AUDIO_ENCODING_SLINEAR_BE, 24 },
     66   1.2       mrg 	{ AUDIO_FILE_ENCODING_LINEAR_32,	AUDIO_ENCODING_SLINEAR_BE, 32 },
     67   1.1       mrg #if 0
     68   1.1       mrg 	/*
     69   1.1       mrg 	 * we should make some of these available.  the, eg ultrasparc, port
     70   1.1       mrg 	 * can use the VIS instructions (if available) do do some of these
     71   1.1       mrg 	 * mpeg ones.
     72   1.1       mrg 	 */
     73   1.1       mrg 	{ AUDIO_FILE_ENCODING_FLOAT,		AUDIO_ENCODING_ULAW,	32 },
     74   1.1       mrg 	{ AUDIO_FILE_ENCODING_DOUBLE,		AUDIO_ENCODING_ULAW,	64 },
     75   1.1       mrg 	{ AUDIO_FILE_ENCODING_ADPCM_G721,	AUDIO_ENCODING_ULAW,	4 },
     76   1.1       mrg 	{ AUDIO_FILE_ENCODING_ADPCM_G722,	AUDIO_ENCODING_ULAW,	0 },
     77   1.1       mrg 	{ AUDIO_FILE_ENCODING_ADPCM_G723_3,	AUDIO_ENCODING_ULAW,	3 },
     78   1.1       mrg 	{ AUDIO_FILE_ENCODING_ADPCM_G723_5,	AUDIO_ENCODING_ULAW,	5 },
     79   1.1       mrg #endif
     80   1.1       mrg 	{ AUDIO_FILE_ENCODING_ALAW_8,		AUDIO_ENCODING_ALAW,	8 },
     81   1.5  christos 	{ -1, -1, -1 }
     82   1.1       mrg };
     83   1.1       mrg 
     84   1.1       mrg int
     85   1.7     joerg audio_sun_to_encoding(int sun_encoding, u_int *encp, u_int *precp)
     86   1.1       mrg {
     87   1.1       mrg 	int i;
     88   1.1       mrg 
     89   1.1       mrg 	for (i = 0; file2sw_encodings[i].file_encoding != -1; i++)
     90   1.1       mrg 		if (file2sw_encodings[i].file_encoding == sun_encoding) {
     91   1.1       mrg 			*precp = file2sw_encodings[i].precision;
     92   1.1       mrg 			*encp = file2sw_encodings[i].encoding;
     93   1.1       mrg 			return (0);
     94   1.1       mrg 		}
     95   1.1       mrg 	return (1);
     96   1.1       mrg }
     97   1.1       mrg 
     98   1.1       mrg int
     99   1.7     joerg audio_encoding_to_sun(int encoding, int precision, int *sunep)
    100   1.1       mrg {
    101   1.1       mrg 	int i;
    102   1.1       mrg 
    103   1.1       mrg 	for (i = 0; file2sw_encodings[i].file_encoding != -1; i++)
    104   1.1       mrg 		if (file2sw_encodings[i].encoding == encoding &&
    105   1.1       mrg 		    file2sw_encodings[i].precision == precision) {
    106   1.1       mrg 			*sunep = file2sw_encodings[i].file_encoding;
    107   1.1       mrg 			return (0);
    108   1.1       mrg 		}
    109   1.1       mrg 	return (1);
    110   1.1       mrg }
    111   1.8       mrg 
    112   1.8       mrg int
    113   1.9       mrg sun_prepare_header(struct track_info *ti, void **hdrp, size_t *lenp, int *leftp)
    114   1.8       mrg {
    115   1.8       mrg 	static int warned = 0;
    116   1.8       mrg 	static sun_audioheader auh;
    117   1.9       mrg 	int sunenc, oencoding = ti->encoding;
    118   1.8       mrg 
    119   1.8       mrg 	/* only perform conversions if we don't specify the encoding */
    120   1.9       mrg 	switch (ti->encoding) {
    121   1.8       mrg 
    122   1.8       mrg 	case AUDIO_ENCODING_ULINEAR_LE:
    123   1.8       mrg #if BYTE_ORDER == LITTLE_ENDIAN
    124   1.8       mrg 	case AUDIO_ENCODING_ULINEAR:
    125   1.8       mrg #endif
    126   1.9       mrg 		if (ti->precision == 16 || ti->precision == 32)
    127   1.9       mrg 			ti->encoding = AUDIO_ENCODING_SLINEAR_BE;
    128   1.8       mrg 		break;
    129   1.8       mrg 
    130   1.8       mrg 	case AUDIO_ENCODING_ULINEAR_BE:
    131   1.8       mrg #if BYTE_ORDER == BIG_ENDIAN
    132   1.8       mrg 	case AUDIO_ENCODING_ULINEAR:
    133   1.8       mrg #endif
    134   1.9       mrg 		if (ti->precision == 16 || ti->precision == 32)
    135   1.9       mrg 			ti->encoding = AUDIO_ENCODING_SLINEAR_BE;
    136   1.8       mrg 		break;
    137   1.8       mrg 
    138   1.8       mrg 	case AUDIO_ENCODING_SLINEAR_LE:
    139   1.8       mrg #if BYTE_ORDER == LITTLE_ENDIAN
    140   1.8       mrg 	case AUDIO_ENCODING_SLINEAR:
    141   1.8       mrg #endif
    142   1.9       mrg 		if (ti->precision == 16 || ti->precision == 32)
    143   1.9       mrg 			ti->encoding = AUDIO_ENCODING_SLINEAR_BE;
    144   1.8       mrg 		break;
    145   1.8       mrg 
    146   1.8       mrg #if BYTE_ORDER == BIG_ENDIAN
    147   1.8       mrg 	case AUDIO_ENCODING_SLINEAR:
    148   1.9       mrg 		ti->encoding = AUDIO_ENCODING_SLINEAR_BE;
    149   1.8       mrg 		break;
    150   1.8       mrg #endif
    151   1.8       mrg 	}
    152  1.11      gson 
    153   1.8       mrg 	/* if we can't express this as a Sun header, don't write any */
    154   1.9       mrg 	if (audio_encoding_to_sun(ti->encoding, ti->precision, &sunenc) != 0) {
    155   1.9       mrg 		if (!ti->qflag && !warned) {
    156   1.8       mrg 			const char *s = audio_enc_from_val(oencoding);
    157   1.8       mrg 
    158   1.8       mrg 			if (s == NULL)
    159   1.8       mrg 				s = "(unknown)";
    160   1.8       mrg 			warnx("failed to convert to sun encoding from %s "
    161   1.8       mrg 			      "(precision %d);\nSun audio header not written",
    162   1.9       mrg 			      s, ti->precision);
    163   1.8       mrg 		}
    164   1.9       mrg 		ti->format = AUDIO_FORMAT_NONE;
    165   1.8       mrg 		warned = 1;
    166   1.8       mrg 		return -1;
    167   1.8       mrg 	}
    168   1.8       mrg 
    169   1.8       mrg 	auh.magic = htonl(AUDIO_FILE_MAGIC);
    170   1.9       mrg 	if (ti->outfd == STDOUT_FILENO)
    171   1.8       mrg 		auh.data_size = htonl(AUDIO_UNKNOWN_SIZE);
    172   1.9       mrg 	else if (ti->total_size != -1)
    173   1.9       mrg 		auh.data_size = htonl(ti->total_size);
    174   1.8       mrg 	else
    175   1.8       mrg 		auh.data_size = 0;
    176   1.8       mrg 	auh.encoding = htonl(sunenc);
    177   1.9       mrg 	auh.sample_rate = htonl(ti->sample_rate);
    178   1.9       mrg 	auh.channels = htonl(ti->channels);
    179   1.9       mrg 	if (ti->header_info) {
    180   1.8       mrg 		int 	len, infolen;
    181   1.8       mrg 
    182   1.9       mrg 		infolen = ((len = strlen(ti->header_info)) + 7) & 0xfffffff8;
    183   1.8       mrg 		*leftp = infolen - len;
    184   1.8       mrg 		auh.hdr_size = htonl(sizeof(auh) + infolen);
    185   1.8       mrg 	} else {
    186   1.8       mrg 		*leftp = sizeof(audio_default_info);
    187   1.8       mrg 		auh.hdr_size = htonl(sizeof(auh) + *leftp);
    188   1.8       mrg 	}
    189   1.8       mrg 	*(sun_audioheader **)hdrp = &auh;
    190   1.8       mrg 	*lenp = sizeof auh;
    191   1.8       mrg 	return 0;
    192   1.8       mrg }
    193   1.8       mrg 
    194   1.8       mrg write_conv_func
    195   1.9       mrg sun_write_get_conv_func(struct track_info *ti)
    196   1.8       mrg {
    197   1.8       mrg 	write_conv_func conv_func = NULL;
    198   1.8       mrg 
    199   1.8       mrg 	/* only perform conversions if we don't specify the encoding */
    200   1.9       mrg 	switch (ti->encoding) {
    201   1.8       mrg 
    202   1.8       mrg 	case AUDIO_ENCODING_ULINEAR_LE:
    203   1.8       mrg #if BYTE_ORDER == LITTLE_ENDIAN
    204   1.8       mrg 	case AUDIO_ENCODING_ULINEAR:
    205   1.8       mrg #endif
    206   1.9       mrg 		if (ti->precision == 16)
    207   1.8       mrg 			conv_func = change_sign16_swap_bytes_le;
    208   1.9       mrg 		else if (ti->precision == 32)
    209   1.8       mrg 			conv_func = change_sign32_swap_bytes_le;
    210   1.8       mrg 		break;
    211   1.8       mrg 
    212   1.8       mrg 	case AUDIO_ENCODING_ULINEAR_BE:
    213   1.8       mrg #if BYTE_ORDER == BIG_ENDIAN
    214   1.8       mrg 	case AUDIO_ENCODING_ULINEAR:
    215   1.8       mrg #endif
    216   1.9       mrg 		if (ti->precision == 16)
    217   1.8       mrg 			conv_func = change_sign16_be;
    218   1.9       mrg 		else if (ti->precision == 32)
    219   1.8       mrg 			conv_func = change_sign32_be;
    220   1.8       mrg 		break;
    221   1.8       mrg 
    222   1.8       mrg 	case AUDIO_ENCODING_SLINEAR_LE:
    223   1.8       mrg #if BYTE_ORDER == LITTLE_ENDIAN
    224   1.8       mrg 	case AUDIO_ENCODING_SLINEAR:
    225   1.8       mrg #endif
    226   1.9       mrg 		if (ti->precision == 16)
    227   1.8       mrg 			conv_func = swap_bytes;
    228   1.9       mrg 		else if (ti->precision == 32)
    229   1.8       mrg 			conv_func = swap_bytes32;
    230   1.8       mrg 		break;
    231   1.8       mrg 	}
    232   1.8       mrg 
    233   1.8       mrg 	return conv_func;
    234   1.8       mrg }
    235