def read(self, bytes): """Try to read a pcm.FrameList of size "bytes".""" #convert bytes to a number of PCM frames frames_read = min(max(bytes / self.bytes_per_frame, 1), self.remaining_frames) if (frames_read > 0): pcm_data = self.file.read(frames_read * self.bytes_per_frame) if (len(pcm_data) < frames_read * self.bytes_per_frame): raise IOError("ssnd chunk ends prematurely") else: framelist = pcm.FrameList(pcm_data, self.channels, self.bits_per_sample, True, True) self.remaining_frames -= framelist.frames if (self.channel_order is not None): return pcm.from_channels( [framelist.channel(channel) for channel in self.channel_order]) else: return framelist else: return pcm.FrameList("", self.channels, self.bits_per_sample, True, True)
def read(self, pcm_frames): # if the stream is exhausted, return an empty pcm.FrameList object if (self.total_pcm_frames == 0): return empty_framelist(self.channels, self.bits_per_sample) # otherwise, read one ALAC frameset's worth of frame data frameset_data = [] frame_channels = self.reader.read(3) + 1 while (frame_channels != 0x8): frameset_data.extend(self.read_frame(frame_channels)) frame_channels = self.reader.read(3) + 1 self.reader.byte_align() # reorder the frameset to Wave order, depending on channel count if ((self.channels == 1) or (self.channels == 2)): pass elif (self.channels == 3): frameset_data = [ frameset_data[1], frameset_data[2], frameset_data[0] ] elif (self.channels == 4): frameset_data = [ frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[3] ] elif (self.channels == 5): frameset_data = [ frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[3], frameset_data[4] ] elif (self.channels == 6): frameset_data = [ frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[5], frameset_data[3], frameset_data[4] ] elif (self.channels == 7): frameset_data = [ frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[6], frameset_data[3], frameset_data[4], frameset_data[5] ] elif (self.channels == 8): frameset_data = [ frameset_data[3], frameset_data[4], frameset_data[0], frameset_data[7], frameset_data[5], frameset_data[6], frameset_data[1], frameset_data[2] ] else: raise ValueError("unsupported channel count") framelist = from_channels([ from_list(channel, 1, self.bits_per_sample, True) for channel in frameset_data ]) # deduct PCM frames from remainder self.total_pcm_frames -= framelist.frames # return samples as a pcm.FrameList object return framelist
def read(self, pcm_frames): if (self.pcm_finished): if (not self.md5_checked): self.reader.mark() try: try: header = Block_Header.read(self.reader) sub_blocks_size = header.block_size - 24 sub_blocks_data = \ self.reader.substream(sub_blocks_size) for sub_block in sub_blocks(sub_blocks_data, sub_blocks_size): if (((sub_block.metadata_function == 6) and (sub_block.nondecoder_data == 1))): if ((sub_block.data.read_bytes(16) != self.md5sum.digest())): raise ValueError("invalid stream MD5 sum") except (IOError, ValueError): #no error if a block isn't found pass finally: self.reader.rewind() self.reader.unmark() return from_list([], self.channels, self.bits_per_sample, True) channels = [] while (True): # in place of a do-while loop try: block_header = Block_Header.read(self.reader) except (ValueError, IOError): self.pcm_finished = True return from_list([], self.channels, self.bits_per_sample, True) sub_blocks_size = block_header.block_size - 24 sub_blocks_data = self.reader.substream(sub_blocks_size) channels.extend(read_block(block_header, sub_blocks_size, sub_blocks_data)) if (block_header.final_block == 1): break if ((block_header.block_index + block_header.block_samples) >= block_header.total_samples): self.pcm_finished = True #combine channels of audio data into single block block = from_channels([from_list(ch, 1, self.bits_per_sample, True) for ch in channels]) #update MD5 sum self.md5sum.update(block.to_bytes(False, self.bits_per_sample > 8)) #return single block of audio data return block
def read(self, bytes): """Try to read a pcm.FrameList of size "bytes".""" #align bytes downward if an odd number is read in bytes -= (bytes % (self.channels * self.bits_per_sample / 8)) pcm_data = self.file.read( max(bytes, self.channels * self.bits_per_sample / 8)) if ((len(pcm_data) == 0) and (self.ssnd_chunk_length > 0)): raise IOError("ssnd chunk ends prematurely") else: self.ssnd_chunk_length -= len(pcm_data) try: framelist = pcm.FrameList(pcm_data, self.channels, self.bits_per_sample, True, True) if (self.channel_order is not None): return pcm.from_channels([framelist.channel(channel) for channel in self.channel_order]) else: return framelist except ValueError: raise IOError("ssnd chunk ends prematurely")
def read(self, bytes): """Try to read a pcm.FrameList of size "bytes".""" #align bytes downward if an odd number is read in bytes -= (bytes % (self.channels * self.bits_per_sample / 8)) pcm_data = self.file.read( max(bytes, self.channels * self.bits_per_sample / 8)) if ((len(pcm_data) == 0) and (self.ssnd_chunk_length > 0)): raise IOError("ssnd chunk ends prematurely") else: self.ssnd_chunk_length -= len(pcm_data) try: framelist = pcm.FrameList(pcm_data, self.channels, self.bits_per_sample, True, True) if (self.channel_order is not None): return pcm.from_channels([ framelist.channel(channel) for channel in self.channel_order ]) else: return framelist except ValueError: raise IOError("ssnd chunk ends prematurely")
def read(self, pcm_frames): #if the stream is exhausted, return an empty pcm.FrameList object if (self.total_pcm_frames == 0): return from_list([], self.channels, self.bits_per_sample, True) #otherwise, read one ALAC frameset's worth of frame data frameset_data = [] frame_channels = self.reader.read(3) + 1 while (frame_channels != 0x8): frameset_data.extend(self.read_frame(frame_channels)) frame_channels = self.reader.read(3) + 1 self.reader.byte_align() #reorder the frameset to Wave order, depending on channel count if ((self.channels == 1) or (self.channels == 2)): pass elif (self.channels == 3): frameset_data = [frameset_data[1], frameset_data[2], frameset_data[0]] elif (self.channels == 4): frameset_data = [frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[3]] elif (self.channels == 5): frameset_data = [frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[3], frameset_data[4]] elif (self.channels == 6): frameset_data = [frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[5], frameset_data[3], frameset_data[4]] elif (self.channels == 7): frameset_data = [frameset_data[1], frameset_data[2], frameset_data[0], frameset_data[6], frameset_data[3], frameset_data[4], frameset_data[5]] elif (self.channels == 8): frameset_data = [frameset_data[3], frameset_data[4], frameset_data[0], frameset_data[7], frameset_data[5], frameset_data[6], frameset_data[1], frameset_data[2]] else: raise ValueError("unsupported channel count") framelist = from_channels([from_list(channel, 1, self.bits_per_sample, True) for channel in frameset_data]) #deduct PCM frames from remainder self.total_pcm_frames -= framelist.frames #return samples as a pcm.FrameList object return framelist
def read(self, pcm_frames): if (self.total_pcm_frames == 0): return FrameList("", self.channels, self.bits_per_sample, True, True) pcm_frames = min(self.pcm_frames_per_tta_frame, self.total_pcm_frames) frame_reader = self.reader.substream( self.frame_sizes[self.current_tta_frame]) crc = CRC32() frame_reader.add_callback(crc.update) self.total_pcm_frames -= pcm_frames self.current_tta_frame += 1 # setup Rice parameters for each channel k0 = [10] * self.channels k1 = [10] * self.channels sum0 = [2**14] * self.channels sum1 = [2**14] * self.channels # list of unfiltered output for each channel unfiltered = [[] for i in range(self.channels)] for f in range(pcm_frames): correlated = [] for (c, ch_output) in enumerate(unfiltered): # read most-significant bits MSB = frame_reader.unary(0) if (MSB == 0): # read least-significant bits unsigned = frame_reader.read(k0[c]) else: # read least-significant bits LSB = frame_reader.read(k1[c]) unshifted = ((MSB - 1) << k1[c]) + LSB unsigned = unshifted + (1 << k0[c]) # adjust sum1 and k1 sum1[c] += (unshifted - (sum1[c] >> 4)) if (sum1[c] < (2**(k1[c] + 4))): k1[c] = max(k1[c] - 1, 0) elif (sum1[c] > (2**(k1[c] + 5))): k1[c] += 1 # adjust sum0 and k0 sum0[c] += (unsigned - (sum0[c] >> 4)) if (sum0[c] < (2**(k0[c] + 4))): k0[c] = max(k0[c] - 1, 0) elif (sum0[c] > (2**(k0[c] + 5))): k0[c] += 1 # apply sign bit if ((unsigned % 2) == 1): # positive ch_output.append((unsigned + 1) // 2) else: # negative ch_output.append(-(unsigned // 2)) # check frame's trailing CRC32 now that reading is finished frame_reader.byte_align() frame_reader.pop_callback() frame_crc = frame_reader.read(32) if (int(crc) != frame_crc): raise ValueError("CRC32 mismatch in frame (0x%8.8X != 0x%8.8X)" % (frame_crc, int(crc))) # run hybrid filter on each channel filtered = [] for unfiltered_ch in unfiltered: filtered.append(tta_filter(self.bits_per_sample, unfiltered_ch)) # run fixed order prediction on each channel predicted = [] for filtered_ch in filtered: predicted.append(fixed_predictor(self.bits_per_sample, filtered_ch)) if (self.channels == 1): # send channel as-is return from_list(predicted[0], 1, self.bits_per_sample, True) else: # decorrelate channels decorrelated = decorrelate(predicted) # return all channels as single FrameList return from_channels([ from_list(decorrelated_ch, 1, self.bits_per_sample, True) for decorrelated_ch in decorrelated ])
def read(self, pcm_frames): if self.stream_finished: return from_channels([empty_framelist(1, self.bits_per_sample) for channel in range(self.channels)]) c = 0 samples = [] unshifted = [] while True: command = self.unsigned(2) if (((0 <= command) and (command <= 3) or (7 <= command) and (command <= 8))): # audio data commands if command == 0: # DIFF0 samples.append(self.read_diff0(self.block_length, self.means[c])) elif command == 1: # DIFF1 samples.append(self.read_diff1(self.block_length, self.wrapped_samples[c])) elif command == 2: # DIFF2 samples.append(self.read_diff2(self.block_length, self.wrapped_samples[c])) elif command == 3: # DIFF3 samples.append(self.read_diff3(self.block_length, self.wrapped_samples[c])) elif command == 7: # QLPC samples.append(self.read_qlpc(self.block_length, self.means[c], self.wrapped_samples[c])) elif command == 8: # ZERO samples.append([0] * self.block_length) # update means for channel self.means[c].append(shnmean(samples[c])) self.means[c] = self.means[c][1:] # wrap samples for next command in channel self.wrapped_samples[c] = samples[c][-(max(3, self.max_LPC)):] # apply left shift to samples if self.left_shift > 0: unshifted.append([s << self.left_shift for s in samples[c]]) else: unshifted.append(samples[c]) c += 1 if c == self.channels: # return a FrameList from shifted data return from_channels([from_list(channel, 1, self.bits_per_sample, self.signed_samples) for channel in unshifted]) else: # non audio commands if command == 4: # QUIT self.stream_finished = True return from_channels( [empty_framelist(1, self.bits_per_sample) for channel in range(self.channels)]) elif command == 5: # BLOCKSIZE self.block_length = self.long() elif command == 6: # BITSHIFT self.left_shift = self.unsigned(2) elif command == 9: # VERBATIM # skip this command during reading size = self.unsigned(5) for i in range(size): self.skip_unsigned(8) else: raise ValueError("unsupported Shorten command")
def read(self, pcm_frames): if (self.total_pcm_frames == 0): return FrameList("", self.channels, self.bits_per_sample, True, True) pcm_frames = min(self.pcm_frames_per_tta_frame, self.total_pcm_frames) frame_reader = self.reader.substream( self.frame_sizes[self.current_tta_frame]) crc = CRC32() frame_reader.add_callback(crc.update) self.total_pcm_frames -= pcm_frames self.current_tta_frame += 1 #setup Rice parameters for each channel k0 = [10] * self.channels k1 = [10] * self.channels sum0 = [2 ** 14] * self.channels sum1 = [2 ** 14] * self.channels #list of unfiltered output for each channel unfiltered = [[] for i in xrange(self.channels)] for f in xrange(pcm_frames): correlated = [] for (c, ch_output) in enumerate(unfiltered): #read most-significant bits MSB = frame_reader.unary(0) if (MSB == 0): #read least-significant bits unsigned = frame_reader.read(k0[c]) else: #read least-significant bits LSB = frame_reader.read(k1[c]) unshifted = ((MSB - 1) << k1[c]) + LSB unsigned = unshifted + (1 << k0[c]) #adjust sum1 and k1 sum1[c] += (unshifted - (sum1[c] >> 4)) if (sum1[c] < (2 ** (k1[c] + 4))): k1[c] = max(k1[c] - 1, 0) elif (sum1[c] > (2 ** (k1[c] + 5))): k1[c] += 1 #adjust sum0 and k0 sum0[c] += (unsigned - (sum0[c] >> 4)) if (sum0[c] < (2 ** (k0[c] + 4))): k0[c] = max(k0[c] - 1, 0) elif (sum0[c] > (2 ** (k0[c] + 5))): k0[c] += 1 #apply sign bit if ((unsigned % 2) == 1): #positive ch_output.append((unsigned + 1) / 2) else: #negative ch_output.append(-(unsigned / 2)) #check frame's trailing CRC32 now that reading is finished frame_reader.byte_align() frame_reader.pop_callback() frame_crc = frame_reader.read(32) if (int(crc) != frame_crc): raise ValueError("CRC32 mismatch in frame (0x%8.8X != 0x%8.8X)" % (frame_crc, int(crc))) #run hybrid filter on each channel filtered = [] for unfiltered_ch in unfiltered: filtered.append( tta_filter(self.bits_per_sample, unfiltered_ch)) #run fixed order prediction on each channel predicted = [] for filtered_ch in filtered: predicted.append( fixed_predictor(self.bits_per_sample, filtered_ch)) if (self.channels == 1): #send channel as-is return from_list(predicted[0], 1, self.bits_per_sample, True) else: #decorrelate channels decorrelated = decorrelate(predicted) #return all channels as single FrameList return from_channels([from_list(decorrelated_ch, 1, self.bits_per_sample, True) for decorrelated_ch in decorrelated])
def read(self, pcm_frames): if (self.stream_finished): return from_channels([ empty_framelist(1, self.bits_per_sample) for channel in range(self.channels) ]) c = 0 samples = [] unshifted = [] while (True): command = self.unsigned(2) if (((0 <= command) and (command <= 3) or (7 <= command) and (command <= 8))): # audio data commands if (command == 0): # DIFF0 samples.append( self.read_diff0(self.block_length, self.means[c])) elif (command == 1): # DIFF1 samples.append( self.read_diff1(self.block_length, self.wrapped_samples[c])) elif (command == 2): # DIFF2 samples.append( self.read_diff2(self.block_length, self.wrapped_samples[c])) elif (command == 3): # DIFF3 samples.append( self.read_diff3(self.block_length, self.wrapped_samples[c])) elif (command == 7): # QLPC samples.append( self.read_qlpc(self.block_length, self.means[c], self.wrapped_samples[c])) elif (command == 8): # ZERO samples.append([0] * self.block_length) # update means for channel self.means[c].append(shnmean(samples[c])) self.means[c] = self.means[c][1:] # wrap samples for next command in channel self.wrapped_samples[c] = samples[c][-(max(3, self.max_LPC)):] # apply left shift to samples if (self.left_shift > 0): unshifted.append( [s << self.left_shift for s in samples[c]]) else: unshifted.append(samples[c]) c += 1 if (c == self.channels): # return a FrameList from shifted data return from_channels([ from_list(channel, 1, self.bits_per_sample, self.signed_samples) for channel in unshifted ]) else: # non audio commands if (command == 4): # QUIT self.stream_finished = True return from_channels([ empty_framelist(1, self.bits_per_sample) for channel in range(self.channels) ]) elif (command == 5): # BLOCKSIZE self.block_length = self.long() elif (command == 6): # BITSHIFT self.left_shift = self.unsigned(2) elif (command == 9): # VERBATIM # skip this command during reading size = self.unsigned(5) for i in range(size): self.skip_unsigned(8) else: raise ValueError("unsupported Shorten command")