// BASS Simple Console Test, copyright (c) 1999-2004 Ian Luck.

#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <conio.h>
#include "bass.h"

// display error messages
void Error(char *text) 
{
	printf("Error(%d): %s\n",BASS_ErrorGetCode(),text);
	BASS_Free();
	ExitProcess(0);
}

DWORD starttime;

// looping synchronizer, resets the clock
void CALLBACK LoopSync(HSYNC handle, DWORD channel, DWORD data, DWORD user)
{
	starttime=timeGetTime();
}

void main(int argc, char **argv)
{
	DWORD chan,act,time,level;
	BOOL ismod;
	QWORD pos;
	int a;

	printf("Simple console mode BASS example : MOD/MPx/OGG/WAV player\n"
			"---------------------------------------------------------\n");

	// check that BASS 2.1 was loaded
	if (BASS_GetVersion()!=MAKELONG(2,1)) {
		printf("BASS version 2.1 was not loaded\n");
		return;
	}

	if (argc!=2) {
		printf("\tusage: contest <file>\n");
		return;
	}

	// setup output - default device
	if (!BASS_Init(1,44100,0,0,NULL))
		Error("Can't initialize device");
	// try streaming the file/url
	if ((chan=BASS_StreamCreateFile(FALSE,argv[1],0,0,BASS_SAMPLE_LOOP))
		|| (chan=BASS_StreamCreateURL(argv[1],0,BASS_SAMPLE_LOOP,NULL,0))) {
		pos=BASS_StreamGetLength(chan);
		if (BASS_StreamGetFilePosition(chan,BASS_FILEPOS_DOWNLOAD)!=-1) {
			// streaming from the internet
			if (pos)
				printf("streaming internet file [%I64d bytes]",pos);
			else
				printf("streaming internet file");
		} else
			printf("streaming file [%I64d bytes]",pos);
		ismod=FALSE;
	} else {
		// try loading the MOD (with looping, sensitive ramping, and calculate the duration)
		if (!(chan=BASS_MusicLoad(FALSE,argv[1],0,0,BASS_SAMPLE_LOOP|BASS_MUSIC_RAMPS|BASS_MUSIC_CALCLEN,0)))
			// not a MOD either
			Error("Can't play the file");
		// count channels
		for (a=0;BASS_MusicGetAttribute(chan,BASS_MUSIC_ATTRIB_VOL_CHAN+a)!=-1;a++);
		printf("playing MOD music \"%s\" [%d chans, %d orders]",BASS_MusicGetName(chan),a,BASS_MusicGetLength(chan,FALSE));
		pos=BASS_MusicGetLength(chan,TRUE);
		ismod=TRUE;
	}

	// display the time length
	if (pos) {
		time=(DWORD)BASS_ChannelBytes2Seconds(chan,pos);
		printf(" %d:%02d\n",time/60,time%60);
	} else // no time length available
		printf("\n");

	// set a synchronizer for when it reaches the end, and start playback
	BASS_ChannelSetSync(chan,BASS_SYNC_END,0,&LoopSync,0);
	BASS_ChannelPlay(chan,FALSE);
	starttime=timeGetTime();

	while (!_kbhit() && (act=BASS_ChannelIsActive(chan))) {
		// display some stuff and wait a bit
		time=timeGetTime()-starttime;
		level=BASS_ChannelGetLevel(chan);
		pos=BASS_ChannelGetPosition(chan);
		if (!ismod)
			printf("pos %09I64d",pos);
		else
			printf("pos %03d:%03d",LOWORD(pos),HIWORD(pos));
		printf(" - time %d:%02d - L ",time/60000,(time/1000)%60);
		if (act==BASS_ACTIVE_STALLED) { // playback has stalled
			printf("-- buffering : %05d --",
				BASS_StreamGetFilePosition(chan,BASS_FILEPOS_DOWNLOAD)-BASS_StreamGetFilePosition(chan,BASS_FILEPOS_DECODE));
		} else {
			for (a=27204;a>200;a=a*2/3) putchar(LOWORD(level)>=a?'*':'-');
			putchar(' ');
			for (a=210;a<32768;a=a*3/2) putchar(HIWORD(level)>=a?'*':'-');
		}
		printf(" R - cpu %.2f%%  \r",BASS_GetCPU());
		Sleep(50);
	}
	printf("                                                                         \r");

	// wind the frequency down...
	BASS_ChannelSlideAttributes(chan,1000,-1,-101,500);
	Sleep(300);
	// ...and fade-out to avoid a "click"
	BASS_ChannelSlideAttributes(chan,-1,-2,-101,200);
	while (BASS_ChannelIsSliding(chan)) Sleep(1);

	BASS_Free();
}
