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 10extern "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) 20typedef 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 29static 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. */ 50enum 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. */ 72struct 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 */ 91struct __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 98static 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 108static 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 */ 121static 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. */ 128struct 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. */ 133void 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 */ 140int 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. */ 144float** cras_channel_conv_matrix_alloc(size_t in_ch, size_t out_ch); 145 146/* Destroys the channel conversion matrix. */ 147void 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 */ 153float **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