def destroy(self): ''' Destroy stream ''' # Note that stopping the service will destroy the endpoint associated with it # hence we delay stopping the service until we are destroying the stream if self.__helper.audio_hydra and self.__helper.audio_hydra.check_started( ): self.__helper.audio_hydra.stop() if self.__config.backing == BACKING_FILE and self.__data.sink_audio_buffer is not None: self._log.info('creating file %s', self.__config.filename) audio_instance = audio_get_instance(self.__config.filename, 'w', allow_encoded=False) audio_instance.add_audio_stream(self.__config.sample_rate, self.__config.sample_width, self.__data.sink_audio_buffer) audio_instance.write() del audio_instance self.__data.sink_audio_buffer = [] if self.__config.metadata_enable: self.__data.stream2.destroy() super(StreamHydraAudioData, self).destroy()
def _init_source_file(self, kwargs): channels = kwargs.pop(CHANNELS, CHANNELS_DEFAULT) channel = kwargs.pop(CHANNEL, CHANNEL_DEFAULT) self.__config.sample_rate = kwargs.pop(SAMPLE_RATE, None) self.__config.sample_width = kwargs.pop(SAMPLE_WIDTH, None) self.__config.frame_size = kwargs.pop(FRAME_SIZE, FRAME_SIZE_DEFAULT) audio_kwargs = { 'channels': channels, # some formats do not require 'sample_rate': self.__config.sample_rate, # some formats do not require 'sample_width': self.__config.sample_width, # some formats do not require } audio_instance = audio_get_instance(self.__config.filename, **audio_kwargs) channels = audio_instance.get_audio_stream_num() # we allow overriding sample_rate from what is in the file self.__config.sample_width = audio_instance.get_audio_stream_sample_width(channel) if channel >= channels: raise RuntimeError('channels:%s channel:%s inconsistency' % (channels, channel)) if audio_instance.get_audio_stream_sample_rate(channel) is None: raise RuntimeError('stream filename:%s sample_rate not set' % (self.__config.filename)) if self.__config.sample_width is None: raise RuntimeError('stream filename:%s sample_width not set' % (self.__config.filename)) # FIXME here we are only supporting streaming manually with kats # might be interesting to add kalsim support in the future whenever is possible self.__data.audio_data = audio_instance.get_audio_stream_data(channel) self.__data.total_samples = len(audio_instance.get_audio_stream_data(channel)) params = get_user_stream_config(self.__config.sample_width) params[STREAM_NAME] = self.__config.filename params[STREAM_RATE] = self.__config.sample_rate # pointless in qwav with packet_info params[STREAM_DATA_WIDTH] = self.__config.sample_width del audio_instance return params
def __new__(cls, stream_type, *args, **kwargs): filename = kwargs.pop(FILENAME) subinterface = kwargs.pop(SUBINTERFACE) channel = kwargs.pop(CHANNEL, 0) if stream_type != STREAM_TYPE_SOURCE: raise RuntimeError( 'stream_type:%s not supported in packet_metadata streams') audio_file = audio_get_instance(filename) # metadata data metadata = audio_file.get_metadata_stream_data(channel) # metadata packet based info packet_info = [] if (hasattr(audio_file, 'get_packet_data_size') and audio_file.get_packet_data_size('metadata', channel)): packet_info = audio_file.get_packet_data('metadata', channel) else: logging.getLogger(__name__).warning( 'filename %s metadata channel %s not found', filename, channel) logging.getLogger(__name__).info('metadata packets:%s', len(packet_info)) # StreamBase parameters kwargs[STREAM_NAME] = filename kwargs[STREAM_RATE] = 0 kwargs[STREAM_DATA_WIDTH] = 8 kwargs[STREAM_DATA] = metadata # the packetiser will control the streaming of data # here we configure kalsim for insert/extract to stream kwargs[STREAM_BACKING] = STREAM_BACKING_KALCMD kwargs[STREAM_FLOW_CONTROL_DRIVE] = STREAM_FLOW_CONTROL_DRIVE_KALCMD kwargs[EXTERNAL_PACKETISER] = True # in the case of audioslot streams this has to be set in spite of # being kalcmd driven and backed and that stream_insert includes the data width kwargs[STREAM_FORMAT] = 8 # instantiate the requested subinterface stream stream_factory = get_instance('stream') instance = stream_factory.get_instance(subinterface, stream_type, *args, **kwargs) # add methods to the stream that will handle the packet based streaming # pylint: disable=protected-access instance._audio_file = audio_file instance._packetiser = Packetiser(instance, metadata, packet_info) instance.old_start = instance.start instance.start = types.MethodType(start, instance) instance.old_stop = instance.stop instance.stop = types.MethodType(stop, instance) return instance
def _init_source_file(self, kwargs): channels = kwargs.pop(CHANNELS, CHANNELS_DEFAULT) channel = kwargs.pop(CHANNEL, CHANNEL_DEFAULT) self.__config.sample_rate = kwargs.pop(SAMPLE_RATE, None) self.__config.sample_width = kwargs.pop(SAMPLE_WIDTH, None) self.__config.frame_size = kwargs.pop(FRAME_SIZE, FRAME_SIZE_DEFAULT) audio_kwargs = { 'channels': channels, # some formats do not require 'sample_rate': self.__config.sample_rate, # some formats do not require 'sample_width': self.__config.sample_width, # some formats do not require } audio_instance = audio_get_instance(self.__config.filename, **audio_kwargs) channels = audio_instance.get_audio_stream_num() # we allow overriding sample_rate from what is in the file self.__config.sample_width = audio_instance.get_audio_stream_sample_width(channel) if channel >= channels: raise RuntimeError('channels:%s channel:%s inconsistency' % (channels, channel)) if audio_instance.get_audio_stream_sample_rate(channel) is None: raise RuntimeError('stream filename:%s sample_rate not set' % (self.__config.filename)) if self.__config.sample_width is None: raise RuntimeError('stream filename:%s sample_width not set' % (self.__config.filename)) # kalsim supports raw and wav files with only 1 stream in the file at the file designated # sample_rate file_sample_rate = audio_instance.get_audio_stream_sample_rate(channel) if (channels == 1 and not self.__config.filename.endswith('.qwav') and (self.__config.sample_rate == file_sample_rate or self.__config.sample_rate is None)): if self.__config.sample_rate is None: self.__config.sample_rate = file_sample_rate params = get_file_user_stream_config(self.__config.filename, self.__config.sample_rate, self.__config.sample_width) self.__data.total_samples = len(audio_instance.get_audio_stream_data(channel)) else: audio_data = audio_instance.get_audio_stream_data(channel) if self.__config.sample_rate is None: self.__config.sample_rate = file_sample_rate # check if the format supports packet_info and that packet_info actually is there if (hasattr(audio_instance, 'get_packet_data_size') and audio_instance.get_packet_data_size('audio', channel)): packet_info = audio_instance.get_packet_data('audio', channel) else: packet_info = self._build_default_packet_info(audio_data, self.__config.frame_size, self.__config.sample_rate) self.__data.source_packetiser = Packetiser(self, audio_data, packet_info) params = get_user_stream_config(self.__config.sample_width) params[STREAM_NAME] = self.__config.filename params[STREAM_RATE] = self.__config.sample_rate # pointless in qwav with packet_info params[STREAM_DATA_WIDTH] = self.__config.sample_width del audio_instance return params
def destroy(self): ''' Destroy stream ''' if self.__config.backing == BACKING_FILE and self.__data.sink_audio_buffer is not None: self._log.info('creating file %s', self.__config.filename) audio_instance = audio_get_instance(self.__config.filename, 'w') audio_instance.add_audio_stream(self.__config.sample_rate, self.__config.sample_width, self.__data.sink_audio_buffer) audio_instance.write() del audio_instance self.__data.sink_audio_buffer = [] super(StreamPcm, self).destroy()
def destroy(self): if self.__config.backing == BACKING_FILE and self.__data.sink_audio_buffer is not None: self._log.info('creating file %s', self.__config.filename) audio_instance = audio_get_instance(self.__config.filename, 'w') audio_instance.add_audio_stream(self.__config.sample_rate, self.__config.sample_width, self.__data.sink_audio_buffer) audio_instance.write() del audio_instance self.__data.sink_audio_buffer = [] # Note that stopping the service will destroy the endpoint associated with it # hence we delay stopping the service until we are destroying the stream if self.__data.sco_service.check_started(): self.__data.sco_service.stop() super(StreamHydraSco, self).destroy()
def __new__(cls, stream_type, *args, **kwargs): filename = kwargs.pop(FILENAME) subinterface = kwargs.pop(SUBINTERFACE) stream_kwargs = {} stream_kwargs[CHANNELS] = kwargs.pop(CHANNELS, 1) stream_kwargs[SAMPLE_RATE] = kwargs.pop(SAMPLE_RATE, 8000) stream_kwargs[SAMPLE_WIDTH] = kwargs.pop(SAMPLE_WIDTH, 16) channel = kwargs.pop(CHANNEL, 0) if stream_type != STREAM_TYPE_SOURCE: raise RuntimeError( 'stream_type:%s not supported in packet_audio streams') audio_file = audio_get_instance(filename, **stream_kwargs) stream_kwargs[CHANNELS] = audio_file.get_audio_stream_num() stream_kwargs[SAMPLE_RATE] = audio_file.get_audio_stream_sample_rate( channel) stream_kwargs[SAMPLE_WIDTH] = audio_file.get_audio_stream_sample_width( channel) # audio data audio_data = audio_file.get_audio_stream_data(channel) # audio packet based data if (hasattr(audio_file, 'get_packet_data_size') and audio_file.get_packet_data_size('audio', channel)): packet_info = audio_file.get_packet_data('audio', channel) else: # we do not have packet based information so we will stream the file # at the right rate in packets of 1 msec # FIXME this does not work for 44.1 KHz sample_rate_khz = int(stream_kwargs[SAMPLE_RATE] / 1000) packet_info = [[ 1000, sample_rate_khz * pos, sample_rate_khz ] for pos in range(int(len(audio_data) / sample_rate_khz))] # FIXME include any pending bytes at the end # do not delay first packet if len(packet_info): packet_info[0][0] = 0 logging.getLogger(__name__).info('metadata packets:%s', len(packet_info)) # StreamBase parameters kwargs[STREAM_NAME] = filename kwargs[STREAM_RATE] = stream_kwargs[SAMPLE_RATE] kwargs[STREAM_DATA_WIDTH] = stream_kwargs[SAMPLE_WIDTH] kwargs[STREAM_DATA] = audio_data # the packetiser will control the streaming of data # here we configure kalsim for insert/extract to stream kwargs[STREAM_BACKING] = STREAM_BACKING_KALCMD kwargs[STREAM_FLOW_CONTROL_DRIVE] = STREAM_FLOW_CONTROL_DRIVE_KALCMD kwargs[EXTERNAL_PACKETISER] = True # in the case of audioslot streams this has to be set in spite of # being kalcmd driven and backed and that stream_insert includes the data width kwargs[STREAM_FORMAT] = audio_file.get_audio_stream_sample_width( channel) # instantiate the requested subinterface stream stream_factory = get_instance('stream') instance = stream_factory.get_instance(subinterface, stream_type, *args, **kwargs) # add methods to the stream that will handle the packet based streaming # pylint: disable=protected-access instance._audio_file = audio_file instance._packetiser = Packetiser(instance, audio_data, packet_info) instance.old_start = instance.start instance.start = types.MethodType(start, instance) instance.old_stop = instance.stop instance.stop = types.MethodType(stop, instance) return instance