Github上有个简单的Alsa DSD测试程序,可以播放DSD,地址位于:https://github.com/zonque/alsa-dsd-player 细看其代码,发现有ALSA_FORMAT_SND_PCM_FORMAT_DSD_U8的定义,详情如下:
#if 1 /* 8-bit DSD */ #define ALSA_FORMAT SND_PCM_FORMAT_DSD_U8 #define SAMPLE_SIZE (sizeof(uint8_t) * 2) #define SAMPLE_RATE_DIV 1 #else /* 16-bit DSD */ #define ALSA_FORMAT SND_PCM_FORMAT_DSD_U16 #define SAMPLE_SIZE (sizeof(uint16_t) * 2) #define SAMPLE_RATE_DIV 2 #endif
那么在Android中能运行这个测试程序吗?ALSA_FORMAT_SND_PCM_FORMAT_DSD_U8似乎是亮点,之前没有看到过。尝试在Android的源码中寻找它的定义,没找到。但是在标准的alsa-lib中找到了:
typedef enum _snd_pcm_format { 125 SND_PCM_FORMAT_UNKNOWN = -1, 127 SND_PCM_FORMAT_S8 = 0, 129 SND_PCM_FORMAT_U8, 131 SND_PCM_FORMAT_S16_LE, 133 SND_PCM_FORMAT_S16_BE, 135 SND_PCM_FORMAT_U16_LE, 137 SND_PCM_FORMAT_U16_BE, 139 SND_PCM_FORMAT_S24_LE, 141 SND_PCM_FORMAT_S24_BE, 143 SND_PCM_FORMAT_U24_LE, 145 SND_PCM_FORMAT_U24_BE, 147 SND_PCM_FORMAT_S32_LE, 149 SND_PCM_FORMAT_S32_BE, 151 SND_PCM_FORMAT_U32_LE, 153 SND_PCM_FORMAT_U32_BE, 155 SND_PCM_FORMAT_FLOAT_LE, 157 SND_PCM_FORMAT_FLOAT_BE, 159 SND_PCM_FORMAT_FLOAT64_LE, 161 SND_PCM_FORMAT_FLOAT64_BE, 163 SND_PCM_FORMAT_IEC958_SUBFRAME_LE, 165 SND_PCM_FORMAT_IEC958_SUBFRAME_BE, 167 SND_PCM_FORMAT_MU_LAW, 169 SND_PCM_FORMAT_A_LAW, 171 SND_PCM_FORMAT_IMA_ADPCM, 173 SND_PCM_FORMAT_MPEG, 175 SND_PCM_FORMAT_GSM, 177 SND_PCM_FORMAT_SPECIAL = 31, 179 SND_PCM_FORMAT_S24_3LE = 32, 181 SND_PCM_FORMAT_S24_3BE, 183 SND_PCM_FORMAT_U24_3LE, 185 SND_PCM_FORMAT_U24_3BE, 187 SND_PCM_FORMAT_S20_3LE, 189 SND_PCM_FORMAT_S20_3BE, 191 SND_PCM_FORMAT_U20_3LE, 193 SND_PCM_FORMAT_U20_3BE, 195 SND_PCM_FORMAT_S18_3LE, 197 SND_PCM_FORMAT_S18_3BE, 199 SND_PCM_FORMAT_U18_3LE, 201 SND_PCM_FORMAT_U18_3BE, 202 /* G.723 (ADPCM) 24 kbit/s, 8 samples in 3 bytes */ 203 SND_PCM_FORMAT_G723_24, 204 /* G.723 (ADPCM) 24 kbit/s, 1 sample in 1 byte */ 205 SND_PCM_FORMAT_G723_24_1B, 206 /* G.723 (ADPCM) 40 kbit/s, 8 samples in 3 bytes */ 207 SND_PCM_FORMAT_G723_40, 208 /* G.723 (ADPCM) 40 kbit/s, 1 sample in 1 byte */ 209 SND_PCM_FORMAT_G723_40_1B, 210 /* Direct Stream Digital (DSD) in 1-byte samples (x8) */ 211 SND_PCM_FORMAT_DSD_U8, 212 /* Direct Stream Digital (DSD) in 2-byte samples (x16) */ 213 SND_PCM_FORMAT_DSD_U16_LE, 214 SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_DSD_U16_LE, 215 216 #if __BYTE_ORDER == __LITTLE_ENDIAN 217 218 SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_LE, 220 SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_LE, 222 SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_LE, 224 SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_LE, 226 SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_LE, 228 SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_LE, 230 SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_LE, 232 SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_LE, 234 SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_LE 235 #elif __BYTE_ORDER == __BIG_ENDIAN 236 237 SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_BE, 239 SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_BE, 241 SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_BE, 243 SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_BE, 245 SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_BE, 247 SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_BE, 249 SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_BE, 251 SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_BE, 253 SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_BE 254 #else 255 #error "Unknown endian" 256 #endif 257 } snd_pcm_format_t;
暂时还不知具体是怎么工作的,是透传DSD数据到硬件?还是alsa-lib中先转换为标准的PCM? 但在Android的alsa-lib中,确实是没有SND_PCM_FORMAT_DSD的定义,应该是被精简掉了。因此只能考虑采用DSD->PCM转换成24bit 176K后,再按照标准的PCM方式来播放。