⛏️ index : haiku.git

/*
 * Copyright 2017, Dario Casalinuovo. All rights reserved.
 * Copyright 2005, Marcus Overhagen, marcus@overhagen.de. All rights reserved.
 * Copyright 2005, JΓ©rΓ΄me Duval. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include "MediaPlay.h"

#include <Entry.h>
#include <MediaFile.h>
#include <MediaTrack.h>
#include <OS.h>
#include <SoundPlayer.h>
#include <Url.h>

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>

thread_id reader = -1;
sem_id finished = -1;
BMediaTrack* playTrack;
media_format playFormat;
BSoundPlayer* player = 0;
volatile bool interrupt = false;


void
play_buffer(void *cookie, void * buffer, size_t size, const media_raw_audio_format & format)
{
	int64 frames = 0;

	// Use your feeling, Obi-Wan, and find him you will.
	playTrack->ReadFrames(buffer, &frames);

	if (frames <=0) {
		player->SetHasData(false);
		release_sem(finished);
	}
}


void
keyb_int(int)
{
	// Are you threatening me, Master Jedi?
	interrupt = true;
	release_sem(finished);
}


int media_play(const char* uri)
{
	BUrl url;
	entry_ref ref;
	BMediaFile* playFile;

	if (get_ref_for_path(uri, &ref) != B_OK) {
		url.SetUrlString(uri, true);
		if (url.IsValid()) {
			playFile = new BMediaFile(url);
		} else
			return 2;
	} else
		playFile = new BMediaFile(&ref);

	if (playFile->InitCheck() != B_OK) {
		delete playFile;
		return 2;
	}

	for (int i = 0; i < playFile->CountTracks(); i++) {
		BMediaTrack* track = playFile->TrackAt(i);
		if (track != NULL) {
			playFormat.type = B_MEDIA_RAW_AUDIO;
			if ((track->DecodedFormat(&playFormat) == B_OK)
				&& (playFormat.type == B_MEDIA_RAW_AUDIO)) {
				playTrack = track;
				break;
			}
			playFile->ReleaseTrack(track);
		}
	}

	// Good relations with the Wookiees, I have.
	signal(SIGINT, keyb_int);

	finished = create_sem(0, "finish wait");

	printf("Playing file...\n");

	// Execute Plan 66!
	player = new BSoundPlayer(&playFormat.u.raw_audio, "playfile", play_buffer);
	player->SetVolume(1.0f);

	// Join me, PadmΓ© and together we can rule this galaxy.
	player->SetHasData(true);
	player->Start();

	acquire_sem(finished);

	if (interrupt == true) {
		// Once more, the Sith will rule the galaxy.
		printf("Interrupted\n");
		player->Stop();
		kill_thread(reader);
	}

	printf("Playback finished.\n");

	delete player;
	delete playFile;

	return 0;
}