
const path = require('path');
const util = require('util');
const EventEmitter = require('events').EventEmitter;
const chalk = require('chalk');

class clsPlayer {
  constructor() {
    this.channel = 0;
    this.soundCard = -1;

    this.bass = require('./basswrapper').basswrapper;
    this.basslib = new this.bass();
    this.position = 0;
    this.duration = 0;
    this.FileName = '';
    this.volume = 0;
    this.mixerChannel = 0;
    this.mixer = 0;
    this.channelCount = 0;
    this.flags = 0;
    this.channelToAdd = 0;

    this.checkPosition = setInterval(() => {
      if(this.channel != 0) {
        if (this.basslib.BASS_ChannelIsActive(this.channel) == this.playerStates.BASS_ACTIVE_PLAYING) {
          let pos = this.Position;
          let dur = this.Duration;
          this.emit(this.playerEvents.positionChange, pos, dur, this.channel);
          pos = null;
          dur = null;
        }
      }
    }, 500);
  }

  get playerEvents() {
    return {
      stateChanged: 'stateChanged',
      positionChange: 'positionChange',
      fileChanged: 'fileChanged',
      playlistFinished: 'playlistFinished',
      vumeter: 'vumeter',
      fadeInStarted: 'fadeInStarted',
      fadeOutStarted: 'fadeOutStarted',
      playbackFinished: 'playbackFinished',
      Error: 'Error',
      announcesStarted: 'announcesStarted',
      announcesFinished: 'announcesFinished'
    }
  }

  get PlayerState() {
    return this.basslib.BASS_ChannelIsActive(this.channel);
  }

  get devices() {
    return this.getDevices();
  }

  set ThreadCount(cnt) {
    this.basslib.BASS_SetConfig(this.basslib.BASS_CONFIG_UPDATETHREADS,cnt);
  }

  get ThreadCount() {
    return this.basslib.BASS_GetConfig(this.basslib.BASS_CONFIG_UPDATETHREADS);
  }

  get channelAttributes() {
    return {
      BASS_ATTRIB_FREQ	:		1,
      BASS_ATTRIB_VOL	:			2,
      BASS_ATTRIB_PAN	:		    3,
      BASS_ATTRIB_EAXMIX	:		4,
      BASS_ATTRIB_NOBUFFER:		5,
      BASS_ATTRIB_VBR	:			6,
      BASS_ATTRIB_CPU	:			7,
      BASS_ATTRIB_SRC	:			8,
      BASS_ATTRIB_NET_RESUME	:	9,
      BASS_ATTRIB_SCANINFO	:	10,
      BASS_ATTRIB_MUSIC_AMPLIFY:	0x100,
      BASS_ATTRIB_MUSIC_PANSEP:	0x101,
      BASS_ATTRIB_MUSIC_PSCALER:	0x102,
      BASS_ATTRIB_MUSIC_BPM		:0x103,
      BASS_ATTRIB_MUSIC_SPEED	:	0x104,
      BASS_ATTRIB_MUSIC_VOL_GLOBAL: 0x105,
      BASS_ATTRIB_MUSIC_ACTIVE:	0x106,
      BASS_ATTRIB_MUSIC_VOL_CHAN:	0x200, // + channel #
      BASS_ATTRIB_MUSIC_VOL_INST:	0x300 // + instrument #
    }
  }

  get speakerAttributes() {
    let BASS_SPEAKER_FRONT = 0x1000000,	// front speakers
        BASS_SPEAKER_REAR = 0x2000000,	// rear/side speakers
        BASS_SPEAKER_CENLFE = 0x3000000,	// center & LFE speakers (5.1)
        BASS_SPEAKER_REAR2 = 0x4000000,	// rear center speakers (7.1)
        BASS_SPEAKER_LEFT = 0x10000000,	// modifier: left
        BASS_SPEAKER_RIGHT = 0x20000000	// modifier: right
    return {
      BASS_SPEAKER_FRONT: BASS_SPEAKER_FRONT,
      BASS_SPEAKER_REAR: BASS_SPEAKER_REAR,
      BASS_SPEAKER_CENLFE: BASS_SPEAKER_CENLFE,
      BASS_SPEAKER_REAR2: BASS_SPEAKER_REAR2,
      BASS_SPEAKER_LEFT: BASS_SPEAKER_LEFT,
      BASS_SPEAKER_RIGHT: BASS_SPEAKER_RIGHT,
      BASS_SPEAKER_FRONTLEFT: BASS_SPEAKER_FRONT | BASS_SPEAKER_LEFT,
      BASS_SPEAKER_FRONTRIGHT: BASS_SPEAKER_FRONT | BASS_SPEAKER_RIGHT,
      BASS_SPEAKER_REARLEFT: BASS_SPEAKER_REAR | BASS_SPEAKER_LEFT,
      BASS_SPEAKER_REARRIGHT: BASS_SPEAKER_REAR | BASS_SPEAKER_RIGHT,
      BASS_SPEAKER_CENTER: BASS_SPEAKER_CENLFE | BASS_SPEAKER_LEFT,
      BASS_SPEAKER_LFE: BASS_SPEAKER_CENLFE | BASS_SPEAKER_RIGHT,
      BASS_SPEAKER_REAR2LEFT: BASS_SPEAKER_REAR2 | BASS_SPEAKER_LEFT,
      BASS_SPEAKER_REAR2RIGHT: BASS_SPEAKER_REAR2 | BASS_SPEAKER_RIGHT
    }
  }

  get bassAttributes() {
    return {
      BASS_SAMPLE_DEFAULT: 0,
      BASS_SAMPLE_8BITS: 1,	// 8 bit
      BASS_SAMPLE_FLOAT: 256,	// 32 bit floating-point
      BASS_SAMPLE_MONO: 2,	// mono
      BASS_SAMPLE_LOOP: 4,	// looped
      BASS_SAMPLE_3D: 8,	// 3D functionality
      BASS_SAMPLE_SOFTWARE: 16,// not using hardware mixing
      BASS_SAMPLE_MUTEMAX: 32,	// mute at max distance (3D only)
      BASS_SAMPLE_VAM: 64,	// DX7 voice allocation & management
      BASS_SAMPLE_FX: 128,	// old implementation of DX8 effects
      BASS_SAMPLE_OVER_VOL: 0x10000,	// override lowest volume
      BASS_SAMPLE_OVER_POS: 0x20000,	// override longest playing
      BASS_SAMPLE_OVER_DIST: 0x30000, // override furthest from listener (3D only)
      BASS_STREAM_PRESCAN: 0x20000, // enable pin-point seeking/length (MP3/MP2/MP1)
      BASS_MP3_SETPOS: 0x20000,
      BASS_STREAM_AUTOFREE: 0x40000,	// automatically free the stream when it stop/ends
      BASS_STREAM_RESTRATE: 0x80000,// restrict the download rate of internet file streams
      BASS_STREAM_BLOCK: 0x100000,// download/play internet file stream in small blocks
      BASS_STREAM_DECODE: 0x200000,// don't play the stream, only decode (BASS_ChannelGetData)
      BASS_STREAM_STATUS: 0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC
    }
  }

  get setConfigAttributes() {
    return {
      BASS_CONFIG_BUFFER			:0,
      BASS_CONFIG_UPDATEPERIOD	:1,
      BASS_CONFIG_GVOL_SAMPLE		:4,
      BASS_CONFIG_GVOL_STREAM		:5,
      BASS_CONFIG_GVOL_MUSIC		:6,
      BASS_CONFIG_CURVE_VOL		:7,
      BASS_CONFIG_CURVE_PAN		:8,
      BASS_CONFIG_FLOATDSP		:9,
      BASS_CONFIG_3DALGORITHM		:10,
      BASS_CONFIG_NET_TIMEOUT		:11,
      BASS_CONFIG_NET_BUFFER		:12,
      BASS_CONFIG_PAUSE_NOPLAY	:13,
      BASS_CONFIG_NET_PREBUF		:15,
      BASS_CONFIG_NET_PASSIVE		:18,
      BASS_CONFIG_REC_BUFFER		:19,
      BASS_CONFIG_NET_PLAYLIST	:21,
      BASS_CONFIG_MUSIC_VIRTUAL	:22,
      BASS_CONFIG_VERIFY			:23,
      BASS_CONFIG_UPDATETHREADS	:24,
      BASS_CONFIG_DEV_BUFFER		:27,
      BASS_CONFIG_VISTA_TRUEPOS	:30,
      BASS_CONFIG_IOS_MIXAUDIO	:34,
      BASS_CONFIG_DEV_DEFAULT		:36,
      BASS_CONFIG_NET_READTIMEOUT	:37,
      BASS_CONFIG_VISTA_SPEAKERS	:38,
      BASS_CONFIG_IOS_SPEAKER		:39,
      BASS_CONFIG_MF_DISABLE		:40,
      BASS_CONFIG_HANDLES			:41,
      BASS_CONFIG_UNICODE			:42,
      BASS_CONFIG_SRC				:43,
      BASS_CONFIG_SRC_SAMPLE		:44,
      BASS_CONFIG_ASYNCFILE_BUFFER :45,
      BASS_CONFIG_OGG_PRESCAN		:47,
      BASS_CONFIG_MF_VIDEO		:48,
      BASS_CONFIG_AIRPLAY			:49,
      BASS_CONFIG_DEV_NONSTOP		:50,
      BASS_CONFIG_IOS_NOCATEGORY	:51,
      BASS_CONFIG_VERIFY_NET		:52,
      BASS_CONFIG_DEV_PERIOD		:53,
      BASS_CONFIG_FLOAT			:54,
      BASS_CONFIG_NET_SEEK		:56
    }

  }

  get mixerAttributes() {
    return {
      BASS_MIXER_BUFFER: 0x2000,	// buffer data for BASS_Mixer_ChannelGetData/Level
      BASS_MIXER_LIMIT: 0x4000,	// limit mixer processing to the amount available from this source
      BASS_MIXER_MATRIX: 0x10000,	// matrix mixing
      BASS_MIXER_PAUSE: 0x20000,// don't process the source
      BASS_MIXER_DOWNMIX: 0x400000,// downmix to stereo/mono
      BASS_MIXER_NORAMPIN: 0x800000 // don't ramp-in the start
    }
  }

  get playerStates() {
    return {
      BASS_ACTIVE_STOPPED: 0,
      BASS_ACTIVE_PLAYING: 1,
      BASS_ACTIVE_STALLED: 2,
      BASS_ACTIVE_PAUSED: 3
    }
  }

  get Duration() {
    let position = 0
    if(this.channel == 0) return 0;
    if (this.basslib.BASS_ChannelIsActive(this.channel) == this.basslib.BASS_ACTIVE_PLAYING) {
      return this.basslib.BASS_ChannelBytes2Seconds(this.channel, this.basslib.BASS_ChannelGetLength(this.channel, 0)) ;
    }
    return 0;
  }

  get isSliding(){
    return this.basslib.BASS_ChannelIsSliding(this.channel, this.basslib.BASS_ATTRIB_VOL)
  }

  set Volume (newVolume) {
    if(this.channel == 0)return;
    console.log("setting volume:" + newVolume + ' for ' + this.channel)
    this.basslib.BASS_ChannelSetAttribute(this.channel, this.basslib.BASS_ATTRIB_VOL, (newVolume / 100));
  }

  get Volume(){
    if(this.channel == 0)return 0;
    return this.basslib.BASS_ChannelGetAttribute(this.channel, this.basslib.BASS_ATTRIB_VOL) * 100;
  }

  get Position() {

    if(this.channel == 0) return 0;
    if (this.basslib.BASS_ChannelIsActive(this.channel) == this.basslib.BASS_ACTIVE_PLAYING) {
      return this.basslib.BASS_ChannelBytes2Seconds(this.channel, this.basslib.BASS_ChannelGetPosition(this.channel, 0)) ;
    }
    return 0;
  }

  get isPlaying() {
    return this.basslib.BASS_ChannelIsActive(this.channel) == this.basslib.BASS_ACTIVE_PLAYING
  }

  set Position(position) {
    var positionInBytes = this.basslib.BASS_ChannelSeconds2Bytes(this.channel, position);
    this.basslib.BASS_ChannelSetPosition(this.channel, positionInBytes,0);
    positionInBytes=null;

  }

  get Duration() {
    var position = 0
    if(this.channel == 0) return 0;
    if (this.basslib.BASS_ChannelIsActive(this.channel) == this.basslib.BASS_ACTIVE_PLAYING) {
      return this.basslib.BASS_ChannelBytes2Seconds(this.channel, this.basslib.BASS_ChannelGetLength(this.channel, 0));

    }
    return 0;
  }
  //-----------------------------

  getDuration(channel) {
    return this.basslib.BASS_ChannelBytes2Seconds(channel, this.basslib.BASS_ChannelGetLength(channel, 0)) ;
  }

  setPosition(channel,position) {
    var positionInBytes = this.basslib.BASS_ChannelSeconds2Bytes(channel, position);
    this.basslib.BASS_ChannelSetPosition(channel, positionInBytes,0);
    positionInBytes = null;
  }

  getDuration(channel) {
    return this.basslib.BASS_ChannelBytes2Seconds(channel, this.basslib.BASS_ChannelGetLength(channel, 0)) ;
  }

  getIsPlaying(chan) {
    return this.basslib.BASS_ChannelIsActive(chan) == this.basslib.BASS_ACTIVE_PLAYING;
  }

  setVolume(channel,newVolume) {
    this.basslib.BASS_ChannelSetAttribute(channel, this.basslib.BASS_ATTRIB_VOL, (newVolume / 100));
  }

  ChannelSlideAttribute (channel, attrib, value, time) {
    this.basslib.BASS_ChannelSlideAttribute(channel, attrib, value, time)
  }

  SlideVolume  (value, duration) {
    this.ChannelSlideAttribute(this.channel, this.basslib.BASS_ATTRIB_VOL, value, duration)
  }

  getDevices () {
    var arr = [];
    arr.push(null)
    var i = 1;
    var info = this.basslib.BASS_GetDeviceInfo(i)
    while ( info) {
      var o = new Object();
      o.name = info.name;
      o.driver = info.driver;
      o.flags = info.flags;
      o.enabled = (info.flags & this.basslib.BASS_DEVICE_ENABLED) == this.basslib.BASS_DEVICE_ENABLED;
      o.IsDefault = (info.flags & this.basslib.BASS_DEVICE_DEFAULT) == this.basslib.BASS_DEVICE_DEFAULT;
      o.IsInitialized = (info.flags & this.basslib.BASS_DEVICE_INIT) == this.basslib.BASS_DEVICE_INIT;
      o.typeDigital = (info.flags & this.basslib.BASS_DEVICE_TYPE_DIGITAL) == this.basslib.BASS_DEVICE_TYPE_DIGITAL;
      o.typeDisplayPort = (info.flags & this.basslib.BASS_DEVICE_TYPE_DISPLAYPORT) == this.basslib.BASS_DEVICE_TYPE_DISPLAYPORT;
      o.typeHandset = (info.flags & this.basslib.BASS_DEVICE_TYPE_HANDSET) == this.basslib.BASS_DEVICE_TYPE_HANDSET;
      o.typeHdmi = (info.flags & this.basslib.BASS_DEVICE_TYPE_HDMI) == this.basslib.BASS_DEVICE_TYPE_HDMI;
      o.typeHeadPhones = (info.flags & this.basslib.BASS_DEVICE_TYPE_HEADPHONES) == this.basslib.BASS_DEVICE_TYPE_HEADPHONES;
      o.typeHeadSet = (info.flags & this.basslib.BASS_DEVICE_TYPE_HEADSET) == this.basslib.BASS_DEVICE_TYPE_HEADSET;
      o.typeLine = (info.flags & this.basslib.BASS_DEVICE_TYPE_LINE) == this.basslib.BASS_DEVICE_TYPE_LINE;
      o.typeMask = (info.flags & this.basslib.BASS_DEVICE_TYPE_MASK) == this.basslib.BASS_DEVICE_TYPE_MASK;
      o.typeMicrophone = (info.flags & this.basslib.BASS_DEVICE_TYPE_MICROPHONE) == this.basslib.BASS_DEVICE_TYPE_MICROPHONE;
      o.typeNetwork = (info.flags & this.basslib.BASS_DEVICE_TYPE_NETWORK) == this.basslib.BASS_DEVICE_TYPE_NETWORK;
      o.typeSPDIF = (info.flags & this.basslib.BASS_DEVICE_TYPE_SPDIF) == this.basslib.BASS_DEVICE_TYPE_SPDIF;
      o.typeSpeakers = (info.flags & this.basslib.BASS_DEVICE_TYPE_SPEAKERS) == this.basslib.BASS_DEVICE_TYPE_SPEAKERS;
      o.index = i;
      arr.push(o);
      i++;
      info = this.basslib.BASS_GetDeviceInfo(i)
    }


    return arr;
  }

  getDevice(device) {
    var devs = this.getDevices();
    if (device == -1) {
      for (var i = 1; i < devs.length; i++) {
        if (devs[i].IsDefault) {
          return devs[i];
        }
      }
    }
    return devs[device];
  }

  getError() {
    return this.basslib.BASS_ErrorGetCode();
  }

  initSoundCard(soundCard, initFlags) {
    this.soundCard = soundCard;
    let dev = this.getDevice(this.soundCard);
    if(!dev.IsInitialized) {
      let result = this.basslib.BASS_Init(this.soundCard, 44100, initFlags);
      if(result) {
        console.log(chalk.bgGreen(this.soundCard, 'init success'));
      } else {
        console.log(chalk.bgRed('Error initializing: ', this.getError()));
      }
      return result;
    } else {
      console.log(chalk.bgGreen('sound card', this.soundCard, 'is already init'));
      return 1;
    }
  }

  openFile(fname, flags) {
    this.flags = flags;
    this.channel = this.basslib.BASS_StreamCreateFile(0, fname, 0, 0, this.flags);
    return this.channel;
  }

  openUrl(url, flags) {
    this.flags = flags;
    this.channel = this.basslib.BASS_StreamCreateURL(url, 0, this.flags, 0, 0);
    if(this.getError()) {
      console.log(this.getError());
    }
  }

  PlayMixer() {
    return this.basslib.BASS_ChannelPlay(this.mixer, 0);
  }

  Stop() {
    clearInterval(this.checkPosition);
    this.basslib.BASS_ChannelStop(this.channel);
  }

  FadeAndStop(fadePeriod) {
    clearInterval(this.checkPosition);
    this.basslib.BASS_ChannelSlideAttribute(this.channel, this.basslib.BASS_ATTRIB_VOL, 0, fadePeriod);
    setTimeout(()=>{this.basslib.BASS_ChannelStop(this.channel);},fadePeriod)

  }
  Pause() {
    let result = this.basslib.BASS_ChannelPause(this.channel);
    if(this.getError()) {
      console.log(this.getError());
    }
  }

  Resume() {
    let result = this.basslib.BASS_ChannelPlay(this.channel, 0);
    if(this.getError()) {
      console.log(this.getError());
    }
  }

  Play() {
    let result = this.basslib.BASS_ChannelPlay(this.channel);
    let endPos = this.Duration;
    let currPos = this.basslib.BASS_ChannelSeconds2Bytes(this.channel, endPos);
    let sync = this.basslib.BASS_ChannelSetSync(this.channel, this.basslib.BASS_SYNC_END, 0, (handle, channel, data, user) => {
      clearInterval(this.checkPosition);
      this.basslib.BASS_ChannelRemoveSync(this.channel, sync);
      let streamFree = this.basslib.BASS_StreamFree(this.channel);
      console.log('song finished: ', streamFree);
      this.emit(this.playerEvents.playbackFinished, this.channel);
    });
    return result;
  }

  PlayFadeIn(volume, fadeDur) {
    let startPos = this.basslib.BASS_ChannelSetSync(this.channel, this.basslib.BASS_SYNC_POS, 0, (handle, channel, data, user) => {
      this.Volume = 0;
      this.basslib.BASS_ChannelSlideAttribute(this.channel, this.basslib.BASS_ATTRIB_VOL, (volume / 100), fadeDur);
      console.log('fade in started, current Vol:', this.Volume);
      this.emit(this.playerEvents.fadeInStarted, this.mixer);
      setTimeout(() => {
        this.basslib.BASS_ChannelRemoveSync(this.channel, startPos);
        console.log('fade in finished, current Vol:', this.Volume)
      }, fadeDur + 1000);
    });

    let result = this.basslib.BASS_ChannelPlay(this.mixer, 0);
    let durBytes = this.basslib.BASS_ChannelGetLength(this.channel, 0);
    let dur = this.basslib.BASS_ChannelBytes2Seconds(this.channel, durBytes);
    let lastFadeSecs = parseInt(dur - (fadeDur / 1000)) * 1;
    let currentPos = this.basslib.BASS_ChannelSeconds2Bytes(this.channel, lastFadeSecs);
    let endPos = this.basslib.BASS_ChannelSetSync(this.channel, this.basslib.BASS_SYNC_POS, currentPos, (handle, channel, data, user) => {
      this.basslib.BASS_ChannelSlideAttribute(this.channel, this.basslib.BASS_ATTRIB_VOL, 0, fadeDur);
      console.log('fade out started, current Vol: ', this.Volume);
      this.emit(this.playerEvents.fadeOutStarted, this.channel);
      setTimeout(() => {
        this.basslib.BASS_ChannelRemoveSync(this.channel, endPos);
        console.log('fade out finished, new Vol: ', this.Volume);
      }, fadeDur + 1000);
    });

    let sync = this.basslib.BASS_ChannelSetSync(this.channel, this.basslib.BASS_SYNC_END, 0, (handle, channel, data, user) => {
      if(handle == sync) {
        clearInterval(this.checkPosition);
        this.basslib.BASS_ChannelRemoveSync(this.channel, sync);
        this.emit(this.playerEvents.playbackFinished, this.channel);
        let streamFree = this.basslib.BASS_StreamFree(this.channel);
        console.log('song finished: ', streamFree);
      }
    });
  }

  setFadeIn(channelToAdd, volume, fadeDur) {
    let startPos = this.basslib.BASS_ChannelSetSync(channelToAdd, this.basslib.BASS_SYNC_POS, 0, (handle, channel, data, user) => {

      this.basslib.BASS_ChannelSetAttribute(channelToAdd, this.basslib.BASS_ATTRIB_VOL, 0);

      //this.basslib.BASS_ChannelSlideAttribute(channelToAdd, this.basslib.BASS_ATTRIB_VOL, 0.8,5000);
      //check here
      this.basslib.BASS_ChannelSlideAttribute(channelToAdd, this.basslib.BASS_ATTRIB_VOL, (volume / 100), fadeDur);
      console.log('fade in started, current Vol: ', this.getVolume(channelToAdd));
      this.emit(this.playerEvents.fadeInStarted, channelToAdd);
      setTimeout(() => {
        this.basslib.BASS_ChannelRemoveSync(channelToAdd, startPos);
        console.log('fade in finished, new Vol: ', this.getVolume(channelToAdd));
      }, fadeDur + 1000);
    });
  }

  setFadeOut(channelToAdd, fadeDur) {
    let dur = this.basslib.BASS_ChannelBytes2Seconds(channelToAdd, this.basslib.BASS_ChannelGetLength(channelToAdd, 0));
    let lastFadeSecs = parseInt(dur - (fadeDur /1000)) * 1;
    let currentPos = this.basslib.BASS_ChannelSeconds2Bytes(channelToAdd, lastFadeSecs);
    let endPos = this.basslib.BASS_ChannelSetSync(channelToAdd, this.basslib.BASS_SYNC_POS, currentPos, (handle, channel, data, user) => {
      this.basslib.BASS_ChannelSlideAttribute(channelToAdd, this.basslib.BASS_ATTRIB_VOL, 0, fadeDur);
      console.log('fade out started, current Vol: ', this.getVolume(channelToAdd));
      this.emit(this.playerEvents.fadeOutStarted, channelToAdd);
      setTimeout(() => {
        this.basslib.BASS_ChannelRemoveSync(channelToAdd, endPos);
        console.log('fade out finished, new Vol: ', this.getVolume(channelToAdd));
      }, fadeDur + 1000);
    });

    let sync = this.basslib.BASS_ChannelSetSync(this.channel, this.basslib.BASS_SYNC_END, 0, (handle, channel, data, user) => {
      clearInterval(this.checkPosition);
      this.basslib.BASS_ChannelRemoveSync(this.channel, sync);
      let streamFree = this.basslib.BASS_StreamFree(this.channel);
      console.log('song finished: ', streamFree);
      this.emit(this.playerEvents.playbackFinished, this.channel);
    });
  }

  setFadeOutForAnnounce(channelToFade, fadeDuration) {
    return this.basslib.BASS_ChannelSlideAttribute(channelToFade, this.basslib.BASS_ATTRIB_VOL, 0, fadeDuration);
  }

  setFadeInForAnnounce(channelToFade, fadeDuration) {
    return this.basslib.BASS_ChannelSlideAttribute(channelToFade, this.basslib.BASS_ATTRIB_VOL, 1, fadeDuration);
  }

  createMixer(channelCount, flags) {
    this.channelCount = channelCount;
    this.flags = flags;
    this.mixer = this.basslib.BASS_Mixer_StreamCreate(44100, this.channelCount, this.flags);
    return this.mixer;
  }

  addChannelToMixer(channelToAdd, flags) {
    this.channelToAdd = channelToAdd;
    this.flags = flags;
    let result = this.basslib.BASS_Mixer_StreamAddChannel(this.mixer, this.channelToAdd, this.flags);

    return result;
  }
  clearPositionEvent(){
    console.log('clearing position event');
    clearInterval(this.checkPosition)
  }
  getVolume(channel) {
    this.channel = channel;
    return this.basslib.BASS_ChannelGetAttribute(this.channel, this.basslib.BASS_ATTRIB_VOL )*100;

  }

  getVumeter(chan){
    let level=this.basslib.BASS_ChannelGetLevel(chan);
    let tmp={};
    tmp.left=this.basslib.BASS_ChannelGetLeftLevel(level);
    tmp.right=this.basslib.BASS_ChannelGetRightLevel(level);
    level=null;
    return tmp;

  }

  setStreamTitle (encoder, title) {
    if (encoder != 0) {
      this.basslib.BASS_Encode_CastSetTitle(encoder, title, null);
    } else {
      console.log('Error setting encoder title: ', this.getError());
    }
  }
}

util.inherits(clsPlayer, EventEmitter);
module.exports = {
  clsPlayer: clsPlayer
};