void xtr_wav_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { init_content_decoder(track); int channels = kt_get_a_channels(track); int sfreq = (int)kt_get_a_sfreq(track); int bps = kt_get_a_bps(track); if (-1 == bps) mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"bits per second (bps)\" element and cannot be extracted.\n")) % m_tid % m_codec_id); xtr_base_c::create_file(master, track); memcpy(&m_wh.riff.id, "RIFF", 4); memcpy(&m_wh.riff.wave_id, "WAVE", 4); memcpy(&m_wh.format.id, "fmt ", 4); memcpy(&m_wh.data.id, "data", 4); put_uint32_le(&m_wh.format.len, 16); put_uint16_le(&m_wh.common.wFormatTag, 1); put_uint16_le(&m_wh.common.wChannels, channels); put_uint32_le(&m_wh.common.dwSamplesPerSec, sfreq); put_uint32_le(&m_wh.common.dwAvgBytesPerSec, channels * sfreq * bps / 8); put_uint16_le(&m_wh.common.wBlockAlign, 4); put_uint16_le(&m_wh.common.wBitsPerSample, bps); m_out->write(&m_wh, sizeof(wave_header)); }
void xtr_tta_c::finish_file() { m_out.reset(); mm_io_cptr in; try { in = mm_file_io_c::open(m_temp_file_name); } catch (mtx::mm_io::exception &ex) { mxerror(boost::format(Y("The temporary file '%1%' could not be opened for reading: %2%.\n")) % m_temp_file_name % ex); } try { m_out = mm_write_buffer_io_c::open(m_file_name, 5 * 1024 * 1024); } catch (mtx::mm_io::exception &ex) { mxerror(boost::format(Y("The file '%1%' could not be opened for writing: %2%.\n")) % m_file_name % ex); } tta_file_header_t tta_header; memcpy(tta_header.signature, "TTA1", 4); if (3 != m_bps) put_uint16_le(&tta_header.audio_format, 1); else put_uint16_le(&tta_header.audio_format, 3); put_uint16_le(&tta_header.channels, m_channels); put_uint16_le(&tta_header.bits_per_sample, m_bps); put_uint32_le(&tta_header.sample_rate, m_sfreq); if (0 >= m_previous_duration) m_previous_duration = (int64_t)(TTA_FRAME_TIME * m_sfreq) * 1000000000ll; put_uint32_le(&tta_header.data_length, (uint32_t)(m_sfreq * (TTA_FRAME_TIME * (m_frame_sizes.size() - 1) + (double)m_previous_duration / 1000000000.0l))); put_uint32_le(&tta_header.crc, 0xffffffff ^ mtx::checksum::calculate_as_uint(mtx::checksum::algorithm_e::crc32_ieee_le, &tta_header, sizeof(tta_file_header_t) - 4, 0xffffffff)); m_out->write(&tta_header, sizeof(tta_file_header_t)); unsigned char *buffer = (unsigned char *)safemalloc(m_frame_sizes.size() * 4); size_t k; for (k = 0; m_frame_sizes.size() > k; ++k) put_uint32_le(buffer + 4 * k, m_frame_sizes[k]); m_out->write(buffer, m_frame_sizes.size() * 4); m_out->write_uint32_le(0xffffffff ^ mtx::checksum::calculate_as_uint(mtx::checksum::algorithm_e::crc32_ieee_le, buffer, m_frame_sizes.size() * 4, 0xffffffff)); safefree(buffer); mxinfo(boost::format(Y("\nThe temporary TTA file for track ID %1% is being copied into the final TTA file. This may take some time.\n")) % m_tid); buffer = (unsigned char *)safemalloc(128000); int nread; do { nread = in->read(buffer, 128000); m_out->write(buffer, nread); } while (nread == 128000); m_out.reset(); unlink(m_temp_file_name.c_str()); }
int mm_io_c::write_uint16_le(uint16_t value) { uint16_t buffer; put_uint16_le(&buffer, value); return write(&buffer, sizeof(uint16_t)); }
void xtr_wav_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { init_content_decoder(track); auto channels = kt_get_a_channels(track); auto sfreq = static_cast<int>(kt_get_a_sfreq(track)); auto bps = kt_get_a_bps(track); auto block_align = bps * channels / boost::math::gcd(8, bps); if (-1 == bps) mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"bits per second (bps)\" element and cannot be extracted.\n")) % m_tid % m_codec_id); xtr_base_c::create_file(master, track); memcpy(&m_wh.riff.id, "RIFF", 4); memcpy(&m_wh.riff.wave_id, "WAVE", 4); memcpy(&m_wh.format.id, "fmt ", 4); memcpy(&m_wh.data.id, "data", 4); put_uint32_le(&m_wh.format.len, 16); put_uint16_le(&m_wh.common.wFormatTag, 1); put_uint16_le(&m_wh.common.wChannels, channels); put_uint32_le(&m_wh.common.dwSamplesPerSec, sfreq); put_uint32_le(&m_wh.common.dwAvgBytesPerSec, channels * sfreq * bps / 8); put_uint16_le(&m_wh.common.wBlockAlign, block_align); put_uint16_le(&m_wh.common.wBitsPerSample, bps); m_out->write(&m_wh, sizeof(wave_header)); if (m_codec_id == MKV_A_PCM_BE) m_byte_swapper = [bps](unsigned char const *src, unsigned char *dst, std::size_t num_bytes) { mtx::bytes::swap_buffer(src, dst, num_bytes, bps / 8); }; }
void xtr_ivf_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { xtr_base_c::create_file(master, track); uint64_t default_duration = kt_get_default_duration(track); default_duration = 0 == default_duration ? 1 : default_duration; uint64_t gcd = boost::math::gcd(static_cast<uint64_t>(100000000), default_duration); m_frame_rate_num = 1000000000ull / gcd; m_frame_rate_den = default_duration / gcd; if ((0xffff < m_frame_rate_num) || (0xffff < m_frame_rate_den)) { uint64_t scale = std::max(m_frame_rate_num, m_frame_rate_den) / 0xffff + 1; m_frame_rate_num = 1000000000ull / scale; m_frame_rate_den = default_duration / scale; if (0 == m_frame_rate_den) m_frame_rate_den = 1; } if (master) mxerror(boost::format(Y("Cannot write track %1% with the CodecID '%2%' to the file '%3%' because " "track %4% with the CodecID '%5%' is already being written to the same file.\n")) % m_tid % m_codec_id % m_file_name % master->m_tid % master->m_codec_id); memcpy(m_file_header.file_magic, "DKIF", 4); memcpy(m_file_header.fourcc, "VP80", 4); put_uint16_le(&m_file_header.header_size, sizeof(m_file_header)); put_uint16_le(&m_file_header.width, kt_get_v_pixel_width(track)); put_uint16_le(&m_file_header.height, kt_get_v_pixel_height(track)); put_uint16_le(&m_file_header.frame_rate_num, m_frame_rate_num); put_uint16_le(&m_file_header.frame_rate_den, m_frame_rate_den); m_out->write(&m_file_header, sizeof(m_file_header)); }