Пример #1
0
    bool decode_run(audio_chunk & p_chunk, abort_callback & p_abort)
    {
        size_t data_size = m_decoder->decode_frame(&sample_buffer);

        if (config.format == 6)
        {
            p_chunk.set_data_floatingpoint_ex(
                sample_buffer.get_ptr(),
                data_size,
                m_decoder->sample_rate,
                config.speakers,
                get_bps_for_format(config.format),
                get_flags_for_format(config.format),
                get_channel_config_for_speakers(config.speakers));
        }
        else
        {
            p_chunk.set_data_fixedpoint_ex(
                sample_buffer.get_ptr(),
                data_size,
                m_decoder->sample_rate,
                config.speakers,
                get_bps_for_format(config.format),
                get_flags_for_format(config.format),
                get_channel_config_for_speakers(config.speakers));
        }

        return (data_size > 0);
    }
Пример #2
0
void output_impl::process_samples(const audio_chunk & p_chunk) {
	pfc::dynamic_assert(m_incoming_ptr == m_incoming.get_size());
	t_samplespec spec;
	spec.fromchunk(p_chunk);
	if (!spec.is_valid()) pfc::throw_exception_with_message< exception_io_data >("Invalid audio stream specifications");
	m_incoming_spec = spec;
	t_size length = p_chunk.get_used_size();
	m_incoming.set_data_fromptr(p_chunk.get_data(),length);
	m_incoming_ptr = 0;
}
Пример #3
0
 bool decode_run(audio_chunk &chunk, abort_callback &abort)
 {
     if (m_current_packet >= m_demuxer->num_packets() + 1)
         return false;
     int64_t pull_packet = m_current_packet;
     if (m_current_packet == m_demuxer->num_packets()) {
         /*
          * If the end padding is shorter than the decoder delay,
          * we already have fed all packets to the decoder but still
          * we have to feed extra packet to pull the final delayed result.
          * Due to overlap+add, samples might not be fully reconstructed
          * anyway...
          */
         if (decoder_delay() <= m_demuxer->end_padding())
             return false;
         else
             pull_packet = m_current_packet - 1;
     }
     auto asbd = m_demuxer->format().asbd;
     uint32_t fpp  = asbd.mFramesPerPacket;
     uint32_t npackets = m_demuxer->read_packets(pull_packet,
                                                 m_packets_per_chunk,
                                                 &m_chunk_buffer, abort);
     if (npackets == 0)
         return false;
     m_current_packet += npackets;
     int64_t trim = std::max(m_current_packet * fpp - m_demuxer->duration()
                             - m_demuxer->start_offset() - decoder_delay(),
                             static_cast<int64_t>(0));
     if (trim >= fpp * npackets)
         return false;
     m_decoder->decode(m_chunk_buffer.data(), m_chunk_buffer.size(),
                       chunk, abort);
     t_size nframes = chunk.get_sample_count();
     unsigned nchannels = chunk.get_channels();
     if (trim > 0) {
         nframes = fpp * npackets - trim;
         chunk.set_sample_count(nframes);
     }
     if (m_start_skip) {
         if (m_start_skip >= nframes) {
             m_start_skip -= nframes;
             return decode_run(chunk, abort);
         }
         uint32_t rest = nframes - m_start_skip;
         uint32_t bpf  = nchannels * sizeof(audio_sample);
         audio_sample *bp = chunk.get_data();
         std::memmove(bp, bp + m_start_skip * nchannels, rest * bpf);
         chunk.set_sample_count(rest);
         m_start_skip = 0;
     }
     update_dynamic_vbr_info(m_current_packet - npackets, m_current_packet);
     return true;
 }
Пример #4
0
bool decode_file(char const * p_path,audio_chunk& chunk, abort_callback & p_abort)
{
    try
    {
        input_helper helper;
        file_info_impl info;
        // open input
        helper.open(service_ptr_t<file>(), make_playable_location(p_path, 0), input_flag_simpledecode, p_abort);
        helper.get_info(0, info, p_abort);
        if (info.get_length() <= 0)
            throw pfc::exception("Track length invalid");
        audio_chunk_impl chunk;
        if (!helper.run(chunk, p_abort)) return false;
        t_uint64 length_samples = audio_math::time_to_samples(info.get_length(), chunk.get_sample_rate());
        while (true)
        {
            bool decode_done = !helper.run(chunk, p_abort);
            if (decode_done) break;
        }
        return true;
    }
    catch (const exception_aborted &) {throw;}
    catch (const std::exception & exc)
    {
        console::formatter() << exc << ": " << p_path;
        return false;
    }
};
Пример #5
0
    void on_chunk(const audio_chunk & chunk)
    {
        unsigned int srate = chunk.get_srate();

        if (send_play)
        {
            send_play = false;

            slim_server->get_connection_manager().send_stream_stop_all();

            slim_server->get_connection_manager().send_audio_gain_all(128, true, 255);

            slim_server->get_connection_manager().send_stream_play_all(
                URL_PATH_STREAM, cfg_http_port.get_value(), g_get_bps(), srate);
        }

        if (is_playing)
        {
            mem_block_container_impl_t<> data;
            chunk.to_raw_data(data, g_get_bps());
            
            std::set<http::server::connection_ptr> connections = 
                http_server->get_connection_manager().get_connections();
            
            std::set<http::server::connection_ptr>::const_iterator c;
            for (c = connections.begin(); c != connections.end(); ++c)
            {
                http::server::connection_ptr c_ptr = (http::server::connection_ptr)(*c);

                // if sending data to the http stream connection returns with 
                // an error, close the connection and call slim server to send
                // a new play command to the device.
                if (c_ptr->send_data(data.get_ptr(), data.get_size()) < 0)
                {
                    std::string mac_address = c_ptr->get_mac_address();

                    http_server->get_connection_manager().stop(c_ptr);

                    if (!mac_address.empty())
                    {
                        slim_server->get_connection_manager().send_stream_play(
                            mac_address, URL_PATH_STREAM, cfg_http_port.get_value(), g_get_bps(), srate);
                    }
                }
            }
        }
    }
Пример #6
0
	bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
		if ( settings.channels == 1 ) {

			std::size_t count = mod->read( settings.samplerate, buffersize, left.data() );
			if ( count == 0 ) {
				return false;
			}
			for ( std::size_t frame = 0; frame < count; frame++ ) {
				buffer[frame*1+0] = left[frame];
			}
			p_chunk.set_data_32( buffer.data(), count, settings.channels, settings.samplerate );
			return true;

		} else if ( settings.channels == 2 ) {

			std::size_t count = mod->read( settings.samplerate, buffersize, left.data(), right.data() );
			if ( count == 0 ) {
				return false;
			}
			for ( std::size_t frame = 0; frame < count; frame++ ) {
				buffer[frame*2+0] = left[frame];
				buffer[frame*2+1] = right[frame];
			}
			p_chunk.set_data_32( buffer.data(), count, settings.channels, settings.samplerate );
			return true;

		} else if ( settings.channels == 4 ) {

			std::size_t count = mod->read( settings.samplerate, buffersize, left.data(), right.data(), rear_left.data(), rear_right.data() );
			if ( count == 0 ) {
				return false;
			}
			for ( std::size_t frame = 0; frame < count; frame++ ) {
				buffer[frame*4+0] = left[frame];
				buffer[frame*4+1] = right[frame];
				buffer[frame*4+2] = rear_left[frame];
				buffer[frame*4+3] = rear_right[frame];
			}
			p_chunk.set_data_32( buffer.data(), count, settings.channels, settings.samplerate );
			return true;

		} else {
			return false;
		}

	}
Пример #7
0
	bool decode_run( audio_chunk & p_chunk, abort_callback & p_abort )
	{
		if (!loop && m_info.musicTimeInMs == ymMusicGetPos(m_player)) return false;
		int nbSample = 500 / sizeof(ymsample);
		sample_buffer.grow_size( nbSample );
		ymMusicCompute(m_player,sample_buffer.get_ptr(), nbSample);
		p_chunk.set_data_fixedpoint( sample_buffer.get_ptr(), nbSample * 2, 44100, 1, 16, audio_chunk::channel_config_mono );
		return true;
	}
Пример #8
0
	bool decode_run( audio_chunk & p_chunk, abort_callback & p_abort )
	{
		if (!loop && is_playing == 0) return false;
		int nbSample = 512;
		sample_buffer.grow_size( nbSample );
		is_playing = ModPlug_Read(m_player, sample_buffer.get_ptr(), nbSample*2);
		p_chunk.set_data_fixedpoint( sample_buffer.get_ptr(), nbSample * 2, 44100, 2, 32, audio_chunk::channel_config_stereo );
		return true;
	}
Пример #9
0
	bool decode_run(audio_chunk & p_chunk,abort_callback & p_abort) {
		enum {
			deltaread = 1024,
		};
		m_buffer.set_size(deltaread * raw_total_sample_width);
		t_size deltaread_done = m_file->read(m_buffer.get_ptr(),deltaread * raw_total_sample_width,p_abort) / raw_total_sample_width;
		if (deltaread_done == 0) return false;//EOF

		p_chunk.set_data_fixedpoint(m_buffer.get_ptr(),deltaread_done * raw_total_sample_width,raw_sample_rate,raw_channels,raw_bits_per_sample,audio_chunk::g_guess_channel_config(raw_channels));
		
		//processed successfully, no EOF
		return true;
	}
Пример #10
0
	bool decode_run(audio_chunk &p_chunk, abort_callback &p_abort)
	{
		int channels = ASAPInfo_GetChannels(ASAP_GetInfo(asap));
		int buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8);
		static BYTE buffer[BUFFERED_BLOCKS * 2 * (BITS_PER_SAMPLE / 8)];

		buffered_bytes = ASAP_Generate(asap, buffer, buffered_bytes,
			BITS_PER_SAMPLE == 8 ? ASAPSampleFormat_U8 : ASAPSampleFormat_S16_L_E);
		if (buffered_bytes == 0)
			return false;
		p_chunk.set_data_fixedpoint(buffer, buffered_bytes, ASAP_SAMPLE_RATE,
			channels, BITS_PER_SAMPLE,
			channels == 2 ? audio_chunk::channel_config_stereo : audio_chunk::channel_config_mono);
		return true;
	}
Пример #11
0
	bool decode_run(audio_chunk &p_chunk, abort_callback &p_abort)
	{
		int channels = module_info.channels;
		int buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8);
		static
#if BITS_PER_SAMPLE == 8
			byte
#else
			short
#endif
			buffer[BUFFERED_BLOCKS * 2];

		buffered_bytes = ASAP_Generate(&asap, buffer, buffered_bytes,
			(ASAP_SampleFormat) BITS_PER_SAMPLE);
		if (buffered_bytes == 0)
			return false;
		p_chunk.set_data_fixedpoint(buffer, buffered_bytes, ASAP_SAMPLE_RATE,
			channels, BITS_PER_SAMPLE,
			channels == 2 ? audio_chunk::channel_config_stereo : audio_chunk::channel_config_mono);
		return true;
	}
Пример #12
0
	void PrepareFFTChunk(audio_chunk const & source, audio_chunk & out, double centerOffset) {
		const t_size channels = source.get_channel_count();
		const t_uint32 sampleRate = source.get_sample_rate();
		FB2K_DYNAMIC_ASSERT( sampleRate > 0 );
		out.set_channels(channels, source.get_channel_config());
		out.set_sample_rate(sampleRate);
		const t_size inSize = source.get_sample_count();
		const t_size fftSize = MatchFFTSize(inSize);
		out.set_sample_count(fftSize);
		out.set_data_size(fftSize * channels);
		if (fftSize >= inSize) { //rare case with *REALLY* small input
			pfc::memcpy_t( out.get_data(), source.get_data(), inSize * channels );
			pfc::memset_null_t( out.get_data() + inSize * channels, (fftSize - inSize) * channels );
		} else { //inSize > fftSize, we're using a subset of source chunk for the job, pick a subset around centerOffset.
			const double baseOffset = pfc::max_t<double>(0, centerOffset - 0.5 * (double)fftSize / (double)sampleRate);
			const t_size baseSample = pfc::min_t<t_size>( (t_size) audio_math::time_to_samples(baseOffset, sampleRate), inSize - fftSize);
			pfc::memcpy_t( out.get_data(), source.get_data() + baseSample * channels, fftSize * channels);
		}
	}