static void init_data(struct linear_priv *data, snd_pcm_format_t src_format, snd_pcm_format_t dst_format) { int src_le, dst_le, src_bytes, dst_bytes; src_bytes = snd_pcm_format_width(src_format) / 8; dst_bytes = snd_pcm_format_width(dst_format) / 8; src_le = snd_pcm_format_little_endian(src_format) > 0; dst_le = snd_pcm_format_little_endian(dst_format) > 0; data->dst_bytes = dst_bytes; data->cvt_endian = src_le != dst_le; data->copy_bytes = src_bytes < dst_bytes ? src_bytes : dst_bytes; if (src_le) { data->copy_ofs = 4 - data->copy_bytes; data->src_ofs = src_bytes - data->copy_bytes; } else data->src_ofs = snd_pcm_format_physical_width(src_format) / 8 - src_bytes; if (dst_le) data->dst_ofs = 4 - data->dst_bytes; else data->dst_ofs = snd_pcm_format_physical_width(dst_format) / 8 - dst_bytes; if (snd_pcm_format_signed(src_format) != snd_pcm_format_signed(dst_format)) { if (dst_le) data->flip = (__force u32)cpu_to_le32(0x80000000); else data->flip = (__force u32)cpu_to_be32(0x80000000); } }
int snd_pcm_linear_convert_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format) { int src_endian, dst_endian, sign, src_width, dst_width; sign = (snd_pcm_format_signed(src_format) != snd_pcm_format_signed(dst_format)); #ifdef SND_LITTLE_ENDIAN src_endian = snd_pcm_format_big_endian(src_format); dst_endian = snd_pcm_format_big_endian(dst_format); #else src_endian = snd_pcm_format_little_endian(src_format); dst_endian = snd_pcm_format_little_endian(dst_format); #endif if (src_endian < 0) src_endian = 0; if (dst_endian < 0) dst_endian = 0; src_width = snd_pcm_format_width(src_format) / 8 - 1; dst_width = snd_pcm_format_width(dst_format) / 8 - 1; return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian; }
int snd_pcm_linear_get_index(snd_pcm_format_t src_format, snd_pcm_format_t dst_format) { int sign, width, pwidth, endian; sign = (snd_pcm_format_signed(src_format) != snd_pcm_format_signed(dst_format)); #ifdef SND_LITTLE_ENDIAN endian = snd_pcm_format_big_endian(src_format); #else endian = snd_pcm_format_little_endian(src_format); #endif if (endian < 0) endian = 0; pwidth = snd_pcm_format_physical_width(src_format); width = snd_pcm_format_width(src_format); if (pwidth == 24) { switch (width) { case 24: width = 0; break; case 20: width = 1; break; case 18: default: width = 2; break; } return width * 4 + endian * 2 + sign + 16; } else { width = width / 8 - 1; return width * 4 + endian * 2 + sign; } }
/** * \brief Return endian info for a PCM sample format * \param format Format * \return 0 swapped, 1 CPU endian, a negative error code if endian independent */ int snd_pcm_format_cpu_endian(snd_pcm_format_t format) { #ifdef SNDRV_LITTLE_ENDIAN return snd_pcm_format_little_endian(format); #else return snd_pcm_format_big_endian(format); #endif }
/** * \brief Return endian info for a PCM sample format * \param format Format * \return 0 little endian, 1 big endian, a negative error code if endian independent */ int snd_pcm_format_big_endian(snd_pcm_format_t format) { int val; val = snd_pcm_format_little_endian(format); if (val < 0) return val; return !val; }
int snd_pcm_lfloat_get_s32_index(snd_pcm_format_t format) { int width, endian; switch (format) { case SND_PCM_FORMAT_FLOAT_LE: case SND_PCM_FORMAT_FLOAT_BE: width = 32; break; case SND_PCM_FORMAT_FLOAT64_LE: case SND_PCM_FORMAT_FLOAT64_BE: width = 64; break; default: return -EINVAL; } #ifdef SND_LITTLE_ENDIAN endian = snd_pcm_format_big_endian(format); #else endian = snd_pcm_format_little_endian(format); #endif return ((width / 32)-1) * 2 + endian; }
/* * pdacf_pcm_prepare - prepare callback for playback and capture */ static int pdacf_pcm_prepare(struct snd_pcm_substream *subs) { struct snd_pdacf *chip = snd_pcm_substream_chip(subs); struct snd_pcm_runtime *runtime = subs->runtime; u16 val, nval, aval; if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE) return -EBUSY; chip->pcm_channels = runtime->channels; chip->pcm_little = snd_pcm_format_little_endian(runtime->format) > 0; #ifdef SNDRV_LITTLE_ENDIAN chip->pcm_swab = snd_pcm_format_big_endian(runtime->format) > 0; #else chip->pcm_swab = chip->pcm_little; #endif if (snd_pcm_format_unsigned(runtime->format)) chip->pcm_xor = 0x80008000; if (pdacf_pcm_clear_sram(chip) < 0) return -EIO; val = nval = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); nval &= ~(PDAUDIOCF_DATAFMT0|PDAUDIOCF_DATAFMT1); switch (runtime->format) { case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_BE: break; default: /* 24-bit */ nval |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1; break; } aval = 0; chip->pcm_sample = 4; switch (runtime->format) { case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_BE: aval = AK4117_DIF_16R; chip->pcm_frame = 2; chip->pcm_sample = 2; break; case SNDRV_PCM_FORMAT_S24_3LE: case SNDRV_PCM_FORMAT_S24_3BE: chip->pcm_sample = 3; /* fall through */ default: /* 24-bit */ aval = AK4117_DIF_24R; chip->pcm_frame = 3; chip->pcm_xor &= 0xffff0000; break; } if (val != nval) { snd_ak4117_reg_write(chip->ak4117, AK4117_REG_IO, AK4117_DIF2|AK4117_DIF1|AK4117_DIF0, aval); pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, nval); } val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER); val &= ~(PDAUDIOCF_IRQLVLEN1); val |= PDAUDIOCF_IRQLVLEN0; pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val); chip->pcm_size = runtime->buffer_size; chip->pcm_period = runtime->period_size; chip->pcm_area = runtime->dma_area; return 0; }
/* peak handler */ static void compute_max_peak(u_char *data, size_t count) { signed int val, max, perc[2], max_peak[2]; static int run = 0; size_t ocount = count; int format_little_endian = snd_pcm_format_little_endian(hwparams.format); int ichans, c; if (vumeter == VUMETER_STEREO) ichans = 2; else ichans = 1; memset(max_peak, 0, sizeof(max_peak)); switch (bits_per_sample) { case 8: { signed char *valp = (signed char *)data; signed char mask = snd_pcm_format_silence(hwparams.format); c = 0; while (count-- > 0) { val = *valp++ ^ mask; val = abs(val); if (max_peak[c] < val) max_peak[c] = val; if (vumeter == VUMETER_STEREO) c = !c; } break; } case 16: { signed short *valp = (signed short *)data; signed short mask = snd_pcm_format_silence_16(hwparams.format); signed short sval; count /= 2; c = 0; while (count-- > 0) { if (format_little_endian) sval = __le16_to_cpu(*valp); else sval = __be16_to_cpu(*valp); sval = abs(sval) ^ mask; if (max_peak[c] < sval) max_peak[c] = sval; valp++; if (vumeter == VUMETER_STEREO) c = !c; } break; } case 24: { unsigned char *valp = data; signed int mask = snd_pcm_format_silence_32(hwparams.format); count /= 3; c = 0; while (count-- > 0) { if (format_little_endian) { val = valp[0] | (valp[1]<<8) | (valp[2]<<16); } else { val = (valp[0]<<16) | (valp[1]<<8) | valp[2]; } /* Correct signed bit in 32-bit value */ if (val & (1<<(bits_per_sample-1))) { val |= 0xff<<24; /* Negate upper bits too */ } val = abs(val) ^ mask; if (max_peak[c] < val) max_peak[c] = val; valp += 3; if (vumeter == VUMETER_STEREO) c = !c; } break; } case 32: { signed int *valp = (signed int *)data; signed int mask = snd_pcm_format_silence_32(hwparams.format); count /= 4; c = 0; while (count-- > 0) { if (format_little_endian) val = __le32_to_cpu(*valp); else val = __be32_to_cpu(*valp); val = abs(val) ^ mask; if (max_peak[c] < val) max_peak[c] = val; valp++; if (vumeter == VUMETER_STEREO) c = !c; } break; } default: if (run == 0) { fprintf(stderr, _("Unsupported bit size %d.\n"), (int)bits_per_sample); run = 1; } return; } max = 1 << (bits_per_sample-1); if (max <= 0) max = 0x7fffffff; for (c = 0; c < ichans; c++) { if (bits_per_sample > 16) perc[c] = max_peak[c] / (max / 100); else perc[c] = max_peak[c] * 100 / max; } if (interleaved && verbose <= 2) { static int maxperc[2]; static time_t t=0; const time_t tt=time(NULL); if(tt>t) { t=tt; maxperc[0] = 0; maxperc[1] = 0; } for (c = 0; c < ichans; c++) if (perc[c] > maxperc[c]) maxperc[c] = perc[c]; putchar('\r'); print_vu_meter(perc, maxperc); fflush(stdout); } else if(verbose==3) { printf(_("Max peak (%li samples): 0x%08x "), (long)ocount, max_peak[0]); for (val = 0; val < 20; val++) if (val <= perc[0] / 5) putchar('#'); else putchar(' '); printf(" %i%%\n", perc[0]); fflush(stdout); } }