def encode_flac(filename, pcmreader, block_size=4096, max_lpc_order=8, adaptive_mid_side=False, mid_side=True, exhaustive_model_search=False, max_residual_partition_order=5): options = Encoding_Options(block_size, max_lpc_order, adaptive_mid_side, mid_side, exhaustive_model_search, max_residual_partition_order, 14 if pcmreader.bits_per_sample <= 16 else 30) streaminfo = STREAMINFO(block_size, block_size, 2 ** 32, 0, pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, 0, md5()) pcmreader = BufferedPCMReader(pcmreader) output_file = open(filename, "wb") writer = BitstreamWriter(output_file, 0) #write placeholder metadata blocks writer.write_bytes("fLaC") writer.build("1u 7u 24u", [1, 0, 34]) streaminfo.write(writer) #walk through PCM reader's FrameLists frame_number = 0 frame = pcmreader.read(block_size * (pcmreader.bits_per_sample / 8) * pcmreader.channels) flac_frame = BitstreamRecorder(0) while (len(frame) > 0): streaminfo.input_update(frame) flac_frame.reset() encode_flac_frame(flac_frame, pcmreader, options, frame_number, frame) streaminfo.output_update(flac_frame) flac_frame.copy(writer) frame_number += 1 frame = pcmreader.read(block_size * (pcmreader.bits_per_sample / 8) * pcmreader.channels) #return to beginning of file and rewrite STREAMINFO block output_file.seek(8, 0) streaminfo.write(writer) writer.close()
def encode_mdat(file, pcmreader, block_size=4096, initial_history=10, history_multiplier=40, maximum_K=14, interlacing_shift=2, min_interlacing_leftweight=0, max_interlacing_leftweight=4): options = Encoding_Options(block_size, initial_history, history_multiplier, maximum_K, interlacing_shift, min_interlacing_leftweight, max_interlacing_leftweight) pcmreader = BufferedPCMReader(pcmreader) mdat = BitstreamWriter(file, 0) mdat_length = ByteCounter() mdat.add_callback(mdat_length.update) frame_sample_sizes = [] frame_byte_sizes = [] frame_file_offsets = [] #write placeholder mdat header mdat.write(32, 0) mdat.write_bytes("mdat") #read FrameList objects until stream is empty frame = pcmreader.read(block_size * pcmreader.channels * (pcmreader.bits_per_sample / 8)) while (len(frame) > 0): frame_sample_sizes.append(frame.frames) frame_file_offsets.append(int(mdat_length)) encode_frameset(mdat, pcmreader, options, frame) frame_byte_sizes.append(int(mdat_length) - frame_file_offsets[-1]) frame = pcmreader.read(block_size * pcmreader.channels * (pcmreader.bits_per_sample / 8)) #finally, return to start of mdat and write actual length mdat.byte_align() mdat.pop_callback() file.seek(0, 0) mdat.write(32, int(mdat_length)) return (frame_sample_sizes, frame_byte_sizes, frame_file_offsets, int(mdat_length))
def encode_mdat( file, pcmreader, block_size=4096, initial_history=10, history_multiplier=40, maximum_k=14, interlacing_shift=2, min_interlacing_leftweight=0, max_interlacing_leftweight=4, ): options = Encoding_Options( block_size, initial_history, history_multiplier, maximum_k, interlacing_shift, min_interlacing_leftweight, max_interlacing_leftweight, ) pcmreader = BufferedPCMReader(pcmreader) mdat = BitstreamWriter(file, 0) total_pcm_frames = 0 frame_byte_sizes = [] # write placeholder mdat header mdat_start = file.tell() mdat.write(32, 0) mdat.write_bytes("mdat") # read FrameList objects until stream is empty frame = pcmreader.read(block_size) while len(frame) > 0: total_pcm_frames += frame.frames frame_start = file.tell() encode_frameset(mdat, pcmreader, options, frame) mdat.flush() frame_byte_sizes.append(file.tell() - frame_start) frame = pcmreader.read(block_size) # finally, return to start of mdat and write actual length file.seek(mdat_start) mdat.write(32, sum(frame_byte_sizes) + 8) return (frame_byte_sizes, total_pcm_frames)
def encode_mdat(file, pcmreader, block_size=4096, initial_history=10, history_multiplier=40, maximum_k=14, interlacing_shift=2, min_interlacing_leftweight=0, max_interlacing_leftweight=4): options = Encoding_Options(block_size, initial_history, history_multiplier, maximum_k, interlacing_shift, min_interlacing_leftweight, max_interlacing_leftweight) pcmreader = BufferedPCMReader(pcmreader) mdat = BitstreamWriter(file, False) total_pcm_frames = 0 frame_byte_sizes = [] # write placeholder mdat header mdat.mark() mdat.write(32, 0) mdat.write_bytes(b"mdat") # read FrameList objects until stream is empty frame = pcmreader.read(block_size) while (len(frame) > 0): total_pcm_frames += frame.frames frame_byte_size = Counter() mdat.add_callback(frame_byte_size.add) encode_frameset(mdat, pcmreader, options, frame) mdat.pop_callback() frame_byte_sizes.append(int(frame_byte_size)) frame = pcmreader.read(block_size) # finally, return to start of mdat and write actual length mdat.rewind() mdat.write(32, sum(frame_byte_sizes) + 8) mdat.unmark() return (frame_byte_sizes, total_pcm_frames)
def encode_mdat(file, pcmreader, block_size=4096, initial_history=10, history_multiplier=40, maximum_k=14, interlacing_shift=2, min_interlacing_leftweight=0, max_interlacing_leftweight=4): options = Encoding_Options(block_size, initial_history, history_multiplier, maximum_k, interlacing_shift, min_interlacing_leftweight, max_interlacing_leftweight) pcmreader = BufferedPCMReader(pcmreader) mdat = BitstreamWriter(file, False) total_pcm_frames = 0 frame_byte_sizes = [] # write placeholder mdat header mdat_start = mdat.getpos() mdat.write(32, 0) mdat.write_bytes(b"mdat") # read FrameList objects until stream is empty frame = pcmreader.read(block_size) while len(frame) > 0: total_pcm_frames += frame.frames frame_byte_size = Counter() mdat.add_callback(frame_byte_size.add) encode_frameset(mdat, pcmreader, options, frame) mdat.pop_callback() frame_byte_sizes.append(int(frame_byte_size)) frame = pcmreader.read(block_size) # finally, return to start of mdat and write actual length mdat.setpos(mdat_start) mdat.write(32, sum(frame_byte_sizes) + 8) return (frame_byte_sizes, total_pcm_frames)
def set_replay_gain(self, replaygain): """given a ReplayGain object, sets the track's gain to those values may raise IOError if unable to modify the file""" from math import log10 from audiotools import TemporaryFile gain_title = int(round((64.82 - replaygain.track_gain) * 256)) if replaygain.track_peak > 0.0: peak_title = int(log10(replaygain.track_peak * 2 ** 15) * 20 * 256) else: peak_title = 0 gain_album = int(round((64.82 - replaygain.album_gain) * 256)) if replaygain.album_peak > 0.0: peak_album = int(log10(replaygain.album_peak * 2 ** 15) * 20 * 256) else: peak_album = 0 #FIXME - check for missing "RG" block and add one if not present metadata = self.get_metadata() writer = BitstreamWriter(TemporaryFile(self.filename), False) writer.write_bytes(b"MPCK") for key, size, block in self.blocks(): if key != b"RG": writer.write_bytes(key) size.build(writer) writer.write_bytes(block) else: writer.write_bytes(b"RG") MPC_Size(2 + 1 + 1 + 2 * 4, 1).build(writer) writer.write(8, 1) writer.write(16, gain_title) writer.write(16, peak_title) writer.write(16, gain_album) writer.write(16, peak_album) if metadata is not None: writer.set_endianness(True) metadata.build(writer) writer.close()
def set_replay_gain(self, replaygain): """given a ReplayGain object, sets the track's gain to those values may raise IOError if unable to modify the file""" from math import log10 from audiotools import TemporaryFile gain_title = int(round((64.82 - replaygain.track_gain) * 256)) if replaygain.track_peak > 0.0: peak_title = int(log10(replaygain.track_peak * 2**15) * 20 * 256) else: peak_title = 0 gain_album = int(round((64.82 - replaygain.album_gain) * 256)) if replaygain.album_peak > 0.0: peak_album = int(log10(replaygain.album_peak * 2**15) * 20 * 256) else: peak_album = 0 #FIXME - check for missing "RG" block and add one if not present metadata = self.get_metadata() writer = BitstreamWriter(TemporaryFile(self.filename), False) writer.write_bytes(b"MPCK") for key, size, block in self.blocks(): if key != b"RG": writer.write_bytes(key) size.build(writer) writer.write_bytes(block) else: writer.write_bytes(b"RG") MPC_Size(2 + 1 + 1 + 2 * 4, 1).build(writer) writer.write(8, 1) writer.write(16, gain_title) writer.write(16, peak_title) writer.write(16, gain_album) writer.write(16, peak_album) if metadata is not None: writer.set_endianness(True) metadata.build(writer) writer.close()
def delete_replay_gain(self): """removes ReplayGain values from file, if any may raise IOError if unable to modify the file""" from audiotools import TemporaryFile writer = BitstreamWriter(TemporaryFile(self.filename), False) writer.write_bytes(b"MPCK") for key, size, block in self.blocks(): if key != b"RG": writer.write_bytes(key) size.build(writer) writer.write_bytes(block) else: writer.write_bytes(b"RG") MPC_Size(2 + 1 + 1 + 2 * 4, 1).build(writer) writer.write(8, 1) writer.write(16, 0) writer.write(16, 0) writer.write(16, 0) writer.write(16, 0) writer.close()
def encode_flac(filename, pcmreader, block_size=4096, max_lpc_order=8, min_residual_partition_order=0, max_residual_partition_order=5, mid_side=True, adaptive_mid_side=False, exhaustive_model_search=False, disable_verbatim_subframes=False, disable_constant_subframes=False, disable_fixed_subframes=False, disable_lpc_subframes=False, padding_size=4096): frame_sizes = [] options = Encoding_Options(block_size, max_lpc_order, adaptive_mid_side, mid_side, exhaustive_model_search, max_residual_partition_order, 14 if pcmreader.bits_per_sample <= 16 else 30) streaminfo = STREAMINFO(block_size, block_size, (2**24) - 1, 0, pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, 0, md5()) pcmreader = BufferedPCMReader(pcmreader) output_file = open(filename, "wb") writer = BitstreamWriter(output_file, False) # write placeholder metadata blocks such as STREAMINFO and PADDING writer.write_bytes("fLaC") writer.build("1u 7u 24u", [0, 0, 34]) streaminfo_start = writer.getpos() streaminfo.write(writer) writer.build("1u 7u 24u", [1, 1, padding_size]) writer.write_bytes(b"\x00" * padding_size) # walk through PCM reader's FrameLists frame_number = 0 frame = pcmreader.read(block_size) flac_frame = BitstreamRecorder(0) while len(frame) > 0: streaminfo.input_update(frame) flac_frame.reset() encode_flac_frame(flac_frame, pcmreader, options, frame_number, frame) frame_sizes.append((flac_frame.bytes(), frame.frames)) streaminfo.output_update(flac_frame) flac_frame.copy(writer) frame_number += 1 frame = pcmreader.read(block_size) # return to beginning of file and rewrite STREAMINFO block writer.setpos(streaminfo_start) streaminfo.write(writer) writer.flush() writer.close() return frame_sizes
def encode_flac(filename, pcmreader, block_size=4096, max_lpc_order=8, min_residual_partition_order=0, max_residual_partition_order=5, mid_side=True, adaptive_mid_side=False, exhaustive_model_search=False, disable_verbatim_subframes=False, disable_constant_subframes=False, disable_fixed_subframes=False, disable_lpc_subframes=False, padding_size=4096): frame_sizes = [] options = Encoding_Options(block_size, max_lpc_order, adaptive_mid_side, mid_side, exhaustive_model_search, max_residual_partition_order, 14 if pcmreader.bits_per_sample <= 16 else 30) streaminfo = STREAMINFO(block_size, block_size, (2 ** 24) - 1, 0, pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, 0, md5()) pcmreader = BufferedPCMReader(pcmreader) output_file = open(filename, "wb") writer = BitstreamWriter(output_file, False) # write placeholder metadata blocks such as STREAMINFO and PADDING writer.write_bytes("fLaC") writer.build("1u 7u 24u", [0, 0, 34]) streaminfo_start = writer.getpos() streaminfo.write(writer) writer.build("1u 7u 24u", [1, 1, padding_size]) writer.write_bytes(b"\x00" * padding_size) # walk through PCM reader's FrameLists frame_number = 0 frame = pcmreader.read(block_size) flac_frame = BitstreamRecorder(0) while len(frame) > 0: streaminfo.input_update(frame) flac_frame.reset() encode_flac_frame(flac_frame, pcmreader, options, frame_number, frame) frame_sizes.append((flac_frame.bytes(), frame.frames)) streaminfo.output_update(flac_frame) flac_frame.copy(writer) frame_number += 1 frame = pcmreader.read(block_size) # return to beginning of file and rewrite STREAMINFO block writer.setpos(streaminfo_start) streaminfo.write(writer) writer.flush() writer.close() return frame_sizes