Exemple #1
0
void AudioSoundIo::writeCallback(int frameCountMin, int frameCountMax)
{
	const struct SoundIoChannelLayout *layout = &m_outstream->layout;
	SoundIoChannelArea *areas;
	int bytesPerSample = m_outstream->bytes_per_sample;
	int err;

	const float gain = mixer()->masterGain();

	int framesLeft = frameCountMax;

	while (framesLeft > 0)
	{
		int frameCount = framesLeft;
		if ((err = soundio_outstream_begin_write(m_outstream, &areas, &frameCount)))
		{
			errorCallback(err);
			return;
		}

		if (!frameCount)
			break;

		for (int frame = 0; frame < frameCount; frame += 1)
		{
			if (m_outBufFrameIndex >= m_outBufFramesTotal)
			{
				m_outBufFramesTotal = getNextBuffer(m_outBuf);
				m_outBufFrameIndex = 0;
			}

			for (int channel = 0; channel < layout->channel_count; channel += 1)
			{
				float sample = gain * m_outBuf[m_outBufFrameIndex][channel];
				memcpy(areas[channel].ptr, &sample, bytesPerSample);
				areas[channel].ptr += areas[channel].step;
			}
			m_outBufFrameIndex += 1;
		}

		if ((err = soundio_outstream_end_write(m_outstream)))
		{
			errorCallback(err);
			return;
		}

		framesLeft -= frameCount;
	}
}
Exemple #2
0
static void write_callback(struct SoundIoOutStream *outstream, int frame_count_min, int frame_count_max) {
    UNUSED(frame_count_min);
    double float_sample_rate = outstream->sample_rate;
    double seconds_per_frame = 1.0 / float_sample_rate;
    struct SoundIoChannelArea *areas;
    int err;

    int frames_left = frame_count_max;

    for (;;) {
        int frame_count = frames_left;
        if ((err = soundio_outstream_begin_write(outstream, &areas, &frame_count))) {
            fprintf(stderr, "unrecoverable stream error: %s\n", soundio_strerror(err));
            exit(1);
        }

        if (!frame_count)
            break;

        const struct SoundIoChannelLayout *layout = &outstream->layout;

        double pitch = 440.0;
        double radians_per_second = pitch * 2.0 * PI;
        for (int frame = 0; frame < frame_count; frame += 1) {
            double sample = (float) sin((seconds_offset + frame * seconds_per_frame) * radians_per_second);
            for (int channel = 0; channel < layout->channel_count; channel += 1) {
                write_sample(areas[channel].ptr, sample);
                areas[channel].ptr += areas[channel].step;
            }
        }
        seconds_offset += seconds_per_frame * frame_count;

        if ((err = soundio_outstream_end_write(outstream))) {
            if (err == SoundIoErrorUnderflow)
                return;
            fprintf(stderr, "unrecoverable stream error: %s\n", soundio_strerror(err));
            exit(1);
        }

        frames_left -= frame_count;
        if (frames_left <= 0)
            break;
    }

    soundio_outstream_pause(outstream, want_pause);
}
Exemple #3
0
//========AUDIO CALLBACK=============
static void write_callback(struct SoundIoOutStream *outstream, int frame_count_min, int frame_count_max)
{
	int frames_left = FRAME_COUNT;//frame_count_max;
	//int channels=outstream->layout.channel_count;
	//printf("min:%i max:%i\n",frame_count_min,frame_count_max);

	int err;
	struct SoundIoChannelArea *areas;

	while(frames_left>0)
	{
		int frame_count = frames_left;

		if((err = soundio_outstream_begin_write(outstream,&areas,&frame_count)))
		{
			printf("soundio_outstream_begin_write ERROR: %s",soundio_strerror(err));
			exit(1);
		}
		if(!frame_count) break;

                for(int frame = 0; frame < frame_count; frame +=1)
                {
			int value1=0;
			int value2=0;
			int n=0;
			for(int i=0;i<MAX_POLYPHONY;i++)
			{
				if(playingsounds[i].sound!=NULL)
				{
					n++;
					value1 += playingsounds[i].sound->buffer[playingsounds[i].pos]*playingsounds[i].volume;
					value2 += playingsounds[i].sound->buffer[playingsounds[i].pos+1]*playingsounds[i].volume;
					playingsounds[i].pos+=2;
					if(playingsounds[i].pos>=playingsounds[i].sound->size)
						playingsounds[i].sound=NULL;
				}
			}
			short *ptr1=(short*)(areas[0].ptr + areas[0].step*frame);
			short *ptr2=(short*)(areas[1].ptr + areas[1].step*frame);
			if(n>0)
			{
				//if (n>10) printf("Poly:%i\n",n);
				*ptr1=(short)(value1/127);
				*ptr2=(short)(value2/127);
			}
			else
			{
				*ptr1=0;
				*ptr2=0;
			}
		}

		if ((err = soundio_outstream_end_write(outstream)))
		{
			printf("soundio_outstream_end_write ERROR: %s",soundio_strerror(err));
			exit(1);
		}

		frames_left -= frame_count;
	}
}
Exemple #4
0
void SoundIoPlayer::write_callback(SoundIoOutStream* out, int frames_min, int frames_max)
{
//	bug_fun();
//	bug_var(frame_count_min);
//	bug_var(frame_count_max);
//	bug_var(out->userdata);
//	bug_var(out);

	auto& player = *reinterpret_cast<SoundIoPlayer*>(out->userdata);
	auto& audio = player.audio;

	channelnum_vec ons;
	// local versions to avoid (postpone) write lock
//	mt_clk::time_point cb_time;

	{
		audiogang::write_lock lock(audio.mtx);

		// 10th second
		auto samples = audio.rate / 10;
		player.pos = std::max(player.pos, player.reg.b);
		auto end = std::min(player.pos + samples, player.reg.e);

		wxThreadEvent evt(wxEVT_THREAD, ID_PlayerPos);
		evt.SetExtraLong(player.pos);
		player.frame.GetEventHandler()->QueueEvent(evt.Clone());

//		reg = player.reg;
//		pos = player.pos;
//		cb_time = player.cb_time;


//		bug_var(player.pos);
//		bug_var(end);
//		bug_var(reg.b);
//		bug_var(reg.e);

		// copy valid channels that are on
		ons.reserve(audio.channels.size());
		for(auto const& channel: audio.channels)
			if(channel.idx < audio.buffers.size())
				ons.push_back(channel.idx);

		auto ons_size = ons.size();

//		if(!ons_size)
//			return;

		SoundIoChannelArea* areas;

		int frames_left = frames_max;

		auto d = std::chrono::milliseconds(100);

		for(;;)
		{
			int frame_count = frames_left;

			int err;
			if((err = soundio_outstream_begin_write(out, &areas, &frame_count)))
			{
				logit("E: Unrecoverable Sound System Error: " << soundio_strerror(err));
//				SoundIoPlayer::ctx_lock_guard lock(player.ctx_mtx);
				player.shutdown();
				return;
			}

			if(!frame_count)
				break;

			SoundIoChannelLayout const* layout = &out->layout;

			for(int frame = 0; frame < frame_count
			&& player.pos < end; ++frame, ++player.pos)
			{
				for(int c = 0; c < layout->channel_count; ++c)
				{
					auto sample = c < ons_size? audio.buffers[ons[c]][player.pos]: 0.0;
					player.write_sample(areas[c].ptr, sample);
					areas[c].ptr += areas[c].step;
				}
			}

			if(player.pos < player.reg.b)
				player.pos = player.reg.b;

			if(player.pos >= player.reg.e)
			{
				player.pos = player.reg.e;
				if(player.loop)
					player.pos = player.reg.b;
				else
				{
//					SoundIoPlayer::ctx_lock_guard lock(player.ctx_mtx);
					player.shutdown();
//					player.ctx.reset();

					return;
				}
			}

//			time_t timer = std::time(0);
//			bug("time: " << std::ctime(&timer));

//			if(mt_clk::now() > cb_time)
//			{
//				player.play_event(ID_PlayerPos);
//				cb_time += d;
//			}

			if((err = soundio_outstream_end_write(out)))
			{
				if(err == SoundIoErrorUnderflow)
					return;
				logit("E: Unrecoverable Sound System Error: " << soundio_strerror(err));
//				SoundIoPlayer::ctx_lock_guard lock(player.ctx_mtx);
				player.shutdown();
				return;
			}

			frames_left -= frame_count;

			if(frames_left <= 0)
				break;
		}
	} // read lock

//	update:
//	audiogang::write_lock lock(audio.mtx);
//	player.pos = pos;
//	player.cb_time = cb_time;
}