Home | History | Annotate | Download | only in common
      1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  */
      5 
      6 #ifndef CRAS_AUDIO_FORMAT_H_
      7 #define CRAS_AUDIO_FORMAT_H_
      8 
      9 #ifdef __cplusplus
     10 extern "C" {
     11 #endif
     12 
     13 #include <stdint.h>
     14 #include <string.h>
     15 
     16 #ifdef __ANDROID__
     17 #include <hardware/audio.h>
     18 #include <tinyalsa/asoundlib.h>
     19 #define PCM_FORMAT_WIDTH(format) pcm_format_to_bits(format)
     20 typedef enum pcm_format snd_pcm_format_t;
     21 
     22 /* libasound audio formats. */
     23 #define SND_PCM_FORMAT_UNKNOWN -1
     24 #define SND_PCM_FORMAT_U8       1
     25 #define SND_PCM_FORMAT_S16_LE   2
     26 #define SND_PCM_FORMAT_S24_LE   6
     27 #define SND_PCM_FORMAT_S32_LE  10
     28 
     29 static inline int audio_format_to_cras_format(audio_format_t audio_format)
     30 {
     31     switch (audio_format) {
     32     case AUDIO_FORMAT_PCM_16_BIT:
     33         return SND_PCM_FORMAT_S16_LE;
     34     case AUDIO_FORMAT_PCM_8_BIT:
     35         return SND_PCM_FORMAT_U8;
     36     case AUDIO_FORMAT_PCM_32_BIT:
     37         return SND_PCM_FORMAT_S32_LE;
     38     case AUDIO_FORMAT_PCM_8_24_BIT:
     39         return SND_PCM_FORMAT_S24_LE;
     40     default:
     41         return SND_PCM_FORMAT_UNKNOWN;
     42     }
     43 }
     44 #else
     45 #include <alsa/asoundlib.h>
     46 #define PCM_FORMAT_WIDTH(format) snd_pcm_format_physical_width(format)
     47 #endif
     48 
     49 /* Identifiers for each channel in audio stream. */
     50 enum CRAS_CHANNEL {
     51 	/* First nine channels matches the
     52 	 * snd_mixer_selem_channel_id_t values.
     53 	 */
     54 	CRAS_CH_FL,
     55 	CRAS_CH_FR,
     56 	CRAS_CH_RL,
     57 	CRAS_CH_RR,
     58 	CRAS_CH_FC,
     59 	CRAS_CH_LFE,
     60 	CRAS_CH_SL,
     61 	CRAS_CH_SR,
     62 	CRAS_CH_RC,
     63 	/* Channels defined both in channel_layout.h and
     64 	 * alsa channel mapping API. */
     65 	CRAS_CH_FLC,
     66 	CRAS_CH_FRC,
     67 	/* Must be the last one */
     68 	CRAS_CH_MAX,
     69 };
     70 
     71 /* Audio format. */
     72 struct cras_audio_format {
     73 	snd_pcm_format_t format;
     74 	size_t frame_rate; /* Hz */
     75 
     76 	// TODO(hychao): use channel_layout to replace num_channels
     77 	size_t num_channels;
     78 
     79 	/* Channel layout whose value represents the index of each
     80 	 * CRAS_CHANNEL in the layout. Value -1 means the channel is
     81 	 * not used. For example: 0,1,2,3,4,5,-1,-1,-1,-1,-1 means the
     82 	 * channel order is FL,FR,RL,RR,FC.
     83 	 */
     84 	int8_t channel_layout[CRAS_CH_MAX];
     85 };
     86 
     87 /* Packed version of audio format, for use in messages. We cannot modify
     88  * the above structure to keep binary compatibility with Chromium.
     89  * If cras_audio_format ever changes, merge the 2 structures.
     90  */
     91 struct __attribute__ ((__packed__)) cras_audio_format_packed {
     92 	int32_t format;
     93 	uint32_t frame_rate;
     94 	uint32_t num_channels;
     95 	int8_t channel_layout[CRAS_CH_MAX];
     96 };
     97 
     98 static inline void pack_cras_audio_format(struct cras_audio_format_packed* dest,
     99 					  const struct cras_audio_format* src)
    100 {
    101 	dest->format = src->format;
    102 	dest->frame_rate = src->frame_rate;
    103 	dest->num_channels = src->num_channels;
    104 	memcpy(dest->channel_layout, src->channel_layout,
    105 		sizeof(src->channel_layout));
    106 }
    107 
    108 static inline void unpack_cras_audio_format(struct cras_audio_format* dest,
    109 				     const struct cras_audio_format_packed* src)
    110 {
    111 	dest->format = (snd_pcm_format_t)src->format;
    112 	dest->frame_rate = src->frame_rate;
    113 	dest->num_channels = src->num_channels;
    114 	memcpy(dest->channel_layout, src->channel_layout,
    115 		sizeof(src->channel_layout));
    116 }
    117 
    118 /* Returns the number of bytes per sample.
    119  * This is bits per smaple / 8 * num_channels.
    120  */
    121 static inline size_t cras_get_format_bytes(const struct cras_audio_format *fmt)
    122 {
    123 	const int bytes = PCM_FORMAT_WIDTH(fmt->format) / 8;
    124 	return (size_t)bytes * fmt->num_channels;
    125 }
    126 
    127 /* Create an audio format structure. */
    128 struct cras_audio_format *cras_audio_format_create(snd_pcm_format_t format,
    129 						   size_t frame_rate,
    130 						   size_t num_channels);
    131 
    132 /* Destroy an audio format struct created with cras_audio_format_crate. */
    133 void cras_audio_format_destroy(struct cras_audio_format *fmt);
    134 
    135 /* Sets the channel layout for given format.
    136  *    format - The format structure to carry channel layout info
    137  *    layout - An integer array representing the position of each
    138  *        channel in enum CRAS_CHANNEL
    139  */
    140 int cras_audio_format_set_channel_layout(struct cras_audio_format *format,
    141 					 const int8_t layout[CRAS_CH_MAX]);
    142 
    143 /* Allocates an empty channel conversion matrix of given size. */
    144 float** cras_channel_conv_matrix_alloc(size_t in_ch, size_t out_ch);
    145 
    146 /* Destroys the channel conversion matrix. */
    147 void cras_channel_conv_matrix_destroy(float **mtx, size_t out_ch);
    148 
    149 /* Creates channel conversion matrix for given input and output format.
    150  * Returns NULL if the conversion is not supported between the channel
    151  * layouts specified in input/ouput formats.
    152  */
    153 float **cras_channel_conv_matrix_create(const struct cras_audio_format *in,
    154 					const struct cras_audio_format *out);
    155 
    156 #ifdef __cplusplus
    157 }
    158 #endif
    159 
    160 #endif /* CRAS_AUDIO_FORMAT_H_ */
    161