void xtr_wavpack4_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { memory_cptr mpriv; init_content_decoder(track); KaxCodecPrivate *priv = FindChild<KaxCodecPrivate>(&track); if (priv) mpriv = decode_codec_private(priv); if (!priv || (2 > mpriv->get_size())) mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id); memcpy(m_version, mpriv->get_buffer(), 2); xtr_base_c::create_file(master, track); m_channels = kt_get_a_channels(track); if ((0 != kt_get_max_blockadd_id(track)) && (0 != m_extract_blockadd_level)) { std::string corr_name = m_file_name; size_t pos = corr_name.rfind('.'); if ((std::string::npos != pos) && (0 != pos)) corr_name.erase(pos + 1); corr_name += "wvc"; try { m_corr_out = mm_write_buffer_io_c::open(corr_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")) % corr_name % ex); } } }
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::create_file(xtr_base_c *, KaxTrackEntry &track) { try { m_out = mm_write_buffer_io_c::open(m_temp_file_name, 5 * 1024 * 1024); } catch (mtx::mm_io::exception &ex) { mxerror(boost::format(Y("Failed to create the temporary file '%1%': %2%\n")) % m_temp_file_name % ex); } m_bps = kt_get_a_bps(track); m_channels = kt_get_a_channels(track); m_sfreq = (int)kt_get_a_sfreq(track); }
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_alac_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { init_content_decoder(track); auto channels = kt_get_a_channels(track); auto priv = FindChild<KaxCodecPrivate>(&track); if (!priv) mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id); m_priv = decode_codec_private(priv); if (m_priv->get_size() != sizeof(alac::codec_config_t)) mxerror(boost::format(Y("ALAC private data size mismatch\n"))); xtr_base_c::create_file(master, track); m_out->write(std::string{"caff"}); // mFileType m_out->write_uint16_be(1); // mFileVersion m_out->write_uint16_be(0); // mFileFlags m_out->write(std::string{"desc"}); // Audio Description chunk m_out->write_uint64_be(32ULL); // mChunkSize m_out->write_double(static_cast<int>(kt_get_a_sfreq(track))); // mSampleRate m_out->write(std::string{"alac"}); // mFormatID m_out->write_uint32_be(0); // mFormatFlags m_out->write_uint32_be(0); // mBytesPerPacket m_out->write_uint32_be(caf::defs::default_frames_per_packet); // mFramesPerPacket m_out->write_uint32_be(channels); // mChannelsPerFrame m_out->write_uint32_be(0); // mBitsPerChannel auto kuki_size = 12 + 36 + 8 + (2 < channels ? 24 : 0); // add the size of ALACChannelLayoutInfo for more than 2 channels m_out->write(std::string{"kuki"}); m_out->write_uint64_be(kuki_size); m_out->write_uint8('\0'); m_out->write_uint8('\0'); m_out->write_uint8('\0'); m_out->write_uint8('\14'); m_out->write(std::string{"frma"}); m_out->write(std::string{"alac"}); m_out->write_uint32_be(12 + sizeof(alac::codec_config_t)); // ALAC Specific Info size = 36 (12 + sizeof(ALAXSpecificConfig)) m_out->write(std::string{"alac"}); // ALAC Specific Info ID m_out->write_uint32_be(0L); // Version Flags m_out->write(m_priv); // audio specific config auto alo = caf::channel_layout_t(); if (2 < channels) { switch (channels) { case 3: alo.channel_layout_tag = caf::channel_layout_t::mpeg_3_0_b; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center; break; case 4: alo.channel_layout_tag = caf::channel_layout_t::mpeg_4_0_b; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::center_surround; break; case 5: alo.channel_layout_tag = caf::channel_layout_t::mpeg_5_0_d; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround; break; case 6: alo.channel_layout_tag = caf::channel_layout_t::mpeg_5_1_d; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround | caf::channel_layout_t::lfe_screen; break; case 7: alo.channel_layout_tag = caf::channel_layout_t::aac_6_1; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround | caf::channel_layout_t::center_surround | caf::channel_layout_t::lfe_screen; break; case 8: alo.channel_layout_tag = caf::channel_layout_t::mpeg_7_1_b; alo.channel_bitmap = caf::channel_layout_t::left | caf::channel_layout_t::right | caf::channel_layout_t::center | caf::channel_layout_t::left_center | caf::channel_layout_t::right_center | caf::channel_layout_t::left_surround | caf::channel_layout_t::right_surround | caf::channel_layout_t::lfe_screen; break; } auto acli = caf::channel_layout_info_t(); put_uint32_be(&acli.channel_layout_info_size, 24); // = sizeof(ALACChannelLayoutInfo) put_uint32_be(&acli.channel_layout_info_id, FOURCC('c', 'h', 'a', 'n')); // = 'chan' put_uint32_be(&acli.channel_layout_tag, alo.channel_layout_tag); m_out->write(&acli, sizeof(acli)); } // Terminator atom m_out->write_uint32_be(8); // Channel Layout Info Size m_out->write_uint32_be(0); // Channel Layout Info ID if (2 < channels) { m_out->write(std::string{"chan"}); // 'chan' chunk immediately following the kuki m_out->write_uint64_be(12ULL); // = sizeof(ALACAudioChannelLayout) m_out->write_uint32_be(alo.channel_layout_tag); m_out->write_uint32_be(alo.channel_bitmap); m_out->write_uint32_be(alo.number_channel_descriptions); } m_free_chunk_offset = m_out->getFilePointer(); // remember the location of m_free_chunk_size = 16384; auto free_chunk = memory_c::alloc(m_free_chunk_size); memset(free_chunk->get_buffer(), 0, sizeof(m_free_chunk_size)); // the 'free' chunk m_out->write(std::string{"free"}); m_out->write_uint64_be(m_free_chunk_size); m_out->write(free_chunk); m_data_chunk_offset = m_out->getFilePointer(); m_out->write(std::string{"data"}); // Audio Data Chunk m_out->write_uint64_be(-1LL); // mChunkSize (= -1 if unknown) m_out->write_uint32_be(1); // mEditCount }