static bool parse_sample_format(const char *src, bool mask, enum sample_format *sample_format_r, const char **endptr_r, GError **error_r) { unsigned long value; char *endptr; enum sample_format sample_format; if (mask && *src == '*') { *sample_format_r = SAMPLE_FORMAT_UNDEFINED; *endptr_r = src + 1; return true; } value = strtoul(src, &endptr, 10); if (endptr == src) { g_set_error(error_r, audio_parser_quark(), 0, "Failed to parse the sample format"); return false; } switch (value) { case 8: sample_format = SAMPLE_FORMAT_S8; break; case 16: sample_format = SAMPLE_FORMAT_S16; break; case 24: if (memcmp(endptr, "_3", 2) == 0) { sample_format = SAMPLE_FORMAT_S24; endptr += 2; } else sample_format = SAMPLE_FORMAT_S24_P32; break; case 32: sample_format = SAMPLE_FORMAT_S32; break; default: g_set_error(error_r, audio_parser_quark(), 0, "Invalid sample format: %lu", value); return false; } assert(audio_valid_sample_format(sample_format)); *sample_format_r = sample_format; *endptr_r = endptr; return true; }
bool audio_check_sample_format(enum sample_format sample_format, GError **error_r) { if (!audio_valid_sample_format(sample_format)) { g_set_error(error_r, audio_format_quark(), 0, "Invalid sample format: %u", sample_format); return false; } return true; }
static enum sample_format audiofile_setup_sample_format(AFfilehandle af_fp) { int fs, bits; afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); if (!audio_valid_sample_format(audiofile_bits_to_sample_format(bits))) { g_debug("input file has %d bit samples, converting to 16", bits); bits = 16; } afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, bits); afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); return audiofile_bits_to_sample_format(bits); }
static void audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) { AFvirtualfile *vf; int fs, frame_count; AFfilehandle af_fp; int bits; struct audio_format audio_format; float total_time; uint16_t bit_rate; int ret, current = 0; char chunk[CHUNK_SIZE]; enum decoder_command cmd; if (!is->seekable) { g_warning("not seekable"); return; } vf = setup_virtual_fops(is); af_fp = afOpenVirtualFile(vf, "r", NULL); if (af_fp == AF_NULL_FILEHANDLE) { g_warning("failed to input stream\n"); return; } afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); if (!audio_valid_sample_format(bits)) { g_debug("input file has %d bit samples, converting to 16", bits); bits = 16; } afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, bits); afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); audio_format.bits = (uint8_t)bits; audio_format.sample_rate = (unsigned int)afGetRate(af_fp, AF_DEFAULT_TRACK); audio_format.channels = (uint8_t)afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK); if (!audio_format_valid(&audio_format)) { g_warning("Invalid audio format: %u:%u:%u\n", audio_format.sample_rate, audio_format.bits, audio_format.channels); afCloseFile(af_fp); return; } frame_count = afGetFrameCount(af_fp, AF_DEFAULT_TRACK); total_time = ((float)frame_count / (float)audio_format.sample_rate); bit_rate = (uint16_t)(is->size * 8.0 / total_time / 1000.0 + 0.5); fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1); decoder_initialized(decoder, &audio_format, true, total_time); do { ret = afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk, CHUNK_SIZE / fs); if (ret <= 0) break; current += ret; cmd = decoder_data(decoder, NULL, chunk, ret * fs, (float)current / (float)audio_format.sample_rate, bit_rate, NULL); if (cmd == DECODE_COMMAND_SEEK) { current = decoder_seek_where(decoder) * audio_format.sample_rate; afSeekFrame(af_fp, AF_DEFAULT_TRACK, current); decoder_command_finished(decoder); cmd = DECODE_COMMAND_NONE; } } while (cmd == DECODE_COMMAND_NONE); afCloseFile(af_fp); }