From 40d25a02ce217fae4e61016645b254bea2dec527 Mon Sep 17 00:00:00 2001 From: Januar Chayadi Date: Fri, 15 Nov 2024 14:16:58 +0700 Subject: [PATCH] Sudah bisa DigitalOutput, DigitalInput. Juga sudah menambahkan class NanoPi. --- src/Audio/AudioFileProperties.java | 14 + src/Audio/AudioPlayer.java | 154 ++++++ src/Audio/Bass.java | 790 +++++++++++++++++++++++++++++ src/Audio/PlaybackEvent.java | 8 + 4 files changed, 966 insertions(+) create mode 100644 src/Audio/AudioFileProperties.java create mode 100644 src/Audio/AudioPlayer.java create mode 100644 src/Audio/Bass.java create mode 100644 src/Audio/PlaybackEvent.java diff --git a/src/Audio/AudioFileProperties.java b/src/Audio/AudioFileProperties.java new file mode 100644 index 0000000..3f41831 --- /dev/null +++ b/src/Audio/AudioFileProperties.java @@ -0,0 +1,14 @@ +package Audio; + + +public class AudioFileProperties { + public final int handle; + public final String filename; + public long Length; + public double duration; + public AudioFileProperties(int handle, String filename){ + this.handle = handle; + this.filename = filename; + } + +} diff --git a/src/Audio/AudioPlayer.java b/src/Audio/AudioPlayer.java new file mode 100644 index 0000000..5c55513 --- /dev/null +++ b/src/Audio/AudioPlayer.java @@ -0,0 +1,154 @@ +package Audio; + +import org.tinylog.Logger; + +public class AudioPlayer { + Bass bass; + int deviceid = -1; + boolean inited = false; + + public AudioPlayer(){ + bass = Bass.Instance; + Logger.info("Bass Version = {}", Integer.toHexString(bass.BASS_GetVersion())); + } + + /** + * Unload Bass + */ + public void Unload(){ + if (inited){ + Logger.info("Freeing Device {}", deviceid); + bass.BASS_SetDevice(deviceid); + bass.BASS_Free(); + } + deviceid = -1; + inited = false; + } + + /** + * Detect Output Devices + */ + public void DetectOutputDevices(){ + Logger.info("Detecting Output Devices..."); + int ii = 1; + while (true){ + Bass.BASS_DEVICEINFO info = new Bass.BASS_DEVICEINFO(); + if (bass.BASS_GetDeviceInfo(ii, info)){ + Logger.info("Device {} = {}, flags = {}", ii, info.name, Integer.toHexString(info.flags)); + ii++; + } else { + break; + } + } + } + + /** + * Open Output Device + * @param device device id, starts from 1 + * @param freq output frequency + * @return true if success + */ + public boolean OpenDevice(int device, int freq){ + int flag = Bass.BASS_DEVICE_REINIT | Bass.BASS_DEVICE_16BITS | Bass.BASS_DEVICE_MONO | Bass.BASS_DEVICE_FREQ; + boolean success = bass.BASS_Init(device, freq, flag); + if (success){ + Logger.info("Device {} opened successfully", device); + deviceid = device; + inited = true; + } else { + Logger.error("Failed to open device {}, Error Code {}", device, bass.BASS_ErrorGetCode()); + } + return success; + } + + /** + * Set Master Volume + * @param value volume value, 0-100 + */ + public void setMasterVolume(int value){ + if (value<0) value = 0; + if (value>100) value = 100; + if (inited){ + if (!bass.BASS_SetVolume(value/100.0f)){ + Logger.error("Failed to set Master Volume to {}, Error Code {}", value, bass.BASS_ErrorGetCode()); + } + } else Logger.info("AudioPlayer not initialized"); + } + + /** + * Get Master Volume + * @return 0 - 100, or -1 if failed + */ + public int getMasterVolume(){ + if (inited){ + float vol = bass.BASS_GetVolume(); + if (vol>=0 && vol<=1){ + return (int)(vol*100); + } + } else Logger.info("AudioPlayer not initialized"); + return -1; + } + + /** + * Open Audio File + * @param filename audio file name to open + * @return AudioFileProperties object or null if failed + */ + public AudioFileProperties OpenAudioFile(String filename){ + if (inited){ + int handle = bass.BASS_StreamCreateFile(false, filename, 0, 0,0); + if (handle!=0){ + Logger.info("Audio file {} opened successfully", filename); + AudioFileProperties prop = new AudioFileProperties(handle, filename); + prop.Length = bass.BASS_ChannelGetLength(handle, Bass.BASS_POS_BYTE); + prop.duration = bass.BASS_ChannelBytes2Seconds(handle, prop.Length); + return prop; + } else Logger.error("Failed to open audio file {}, Error Code {}", filename, bass.BASS_ErrorGetCode()); + } else Logger.info("AudioPlayer not initialized"); + return null; + } + + /** + * Close Audio File + * @param prop AudioFileProperties object to close + */ + public void CloseAudioFile(AudioFileProperties prop) { + if (inited) { + if (prop != null) { + if (!bass.BASS_StreamFree(prop.handle)) { + { + Logger.error("Failed to close audio file {}, Error Code {}", prop.filename, bass.BASS_ErrorGetCode()); + } + } else Logger.error("AudioFileProperties is null"); + } else Logger.info("AudioPlayer not initialized"); + } + } + + public void PlayAudioFile(AudioFileProperties prop, boolean looping, PlaybackEvent event){ + if (inited){ + if (prop!=null){ + if (bass.BASS_ChannelStart(prop.handle)){ + if (looping) bass.BASS_ChannelFlags(prop.handle, Bass.BASS_SAMPLE_LOOP, Bass.BASS_SAMPLE_LOOP); + if (event!=null) event.onPlaybackStart(prop); + int devfailsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_DEV_FAIL,0, (handle, channel, data, user)->{ + if (event!=null) event.onPlaybackFailure(prop, "Device Failure"); + }, null); + if (devfailsync==0) Logger.error("Failed to set Device Failure Sync, Error Code {}", bass.BASS_ErrorGetCode()); + int endsync = bass.BASS_ChannelSetSync(prop.handle, Bass.BASS_SYNC_END, 0, (handle, channel, data, user)->{ + if (looping) { + if (event!=null) event.onPlaybackLooped(prop); + } else if (event!=null) event.onPlaybackFinished(prop); + }, null); + if (endsync==0) Logger.error("Failed to set End Sync, Error Code {}", bass.BASS_ErrorGetCode()); + } else { + if (event!=null) event.onPlaybackFailure(prop, String.format("Failed to play audio file %s, Error Code %d", prop.filename, bass.BASS_ErrorGetCode())); + } + } else { + if (event!=null) event.onPlaybackFailure(null, "AudioFileProperties is null"); + } + } else { + if (event!=null) event.onPlaybackFailure(prop, "AudioPlayer not initialized"); + } + } + +} diff --git a/src/Audio/Bass.java b/src/Audio/Bass.java new file mode 100644 index 0000000..59c4862 --- /dev/null +++ b/src/Audio/Bass.java @@ -0,0 +1,790 @@ +package Audio; + +import com.sun.jna.*; + + +@SuppressWarnings("unused") +public interface Bass extends Library { + + Bass Instance = (Bass) Native.load("bass", Bass.class); + int BASSVERSION = 0x204; // API version + String BASSVERSIONTEXT = "2.4"; + + // Error codes returned by BASS_ErrorGetCode + int BASS_OK = 0; // all is OK + int BASS_ERROR_MEM = 1; // memory error + int BASS_ERROR_FILEOPEN = 2; // can't open the file + int BASS_ERROR_DRIVER = 3; // can't find a free/valid driver + int BASS_ERROR_BUFLOST = 4; // the sample buffer was lost + int BASS_ERROR_HANDLE = 5; // invalid handle + int BASS_ERROR_FORMAT = 6; // unsupported sample format + int BASS_ERROR_POSITION = 7; // invalid position + int BASS_ERROR_INIT = 8; // BASS_Init has not been successfully called + int BASS_ERROR_START = 9; // BASS_Start has not been successfully called + int BASS_ERROR_SSL = 10; // SSL/HTTPS support isn't available + int BASS_ERROR_REINIT = 11; // device needs to be reinitialized + int BASS_ERROR_ALREADY = 14; // already initialized/paused/whatever + int BASS_ERROR_NOTAUDIO = 17; // file does not contain audio + int BASS_ERROR_NOCHAN = 18; // can't get a free channel + int BASS_ERROR_ILLTYPE = 19; // an illegal type was specified + int BASS_ERROR_ILLPARAM = 20; // an illegal parameter was specified + int BASS_ERROR_NO3D = 21; // no 3D support + int BASS_ERROR_NOEAX = 22; // no EAX support + int BASS_ERROR_DEVICE = 23; // illegal device number + int BASS_ERROR_NOPLAY = 24; // not playing + int BASS_ERROR_FREQ = 25; // illegal sample rate + int BASS_ERROR_NOTFILE = 27; // the stream is not a file stream + int BASS_ERROR_NOHW = 29; // no hardware voices available + int BASS_ERROR_EMPTY = 31; // the file has no sample data + int BASS_ERROR_NONET = 32; // no internet connection could be opened + int BASS_ERROR_CREATE = 33; // couldn't create the file + int BASS_ERROR_NOFX = 34; // effects are not available + int BASS_ERROR_NOTAVAIL = 37; // requested data/action is not available + int BASS_ERROR_DECODE = 38; // the channel is a "decoding channel" + int BASS_ERROR_DX = 39; // a sufficient DirectX version is not installed + int BASS_ERROR_TIMEOUT = 40; // connection timedout + int BASS_ERROR_FILEFORM = 41; // unsupported file format + int BASS_ERROR_SPEAKER = 42; // unavailable speaker + int BASS_ERROR_VERSION = 43; // invalid BASS version (used by add-ons) + int BASS_ERROR_CODEC = 44; // codec is not available/supported + int BASS_ERROR_ENDED = 45; // the channel/file has ended + int BASS_ERROR_BUSY = 46; // the device is busy + int BASS_ERROR_UNSTREAMABLE = 47; // unstreamable file + int BASS_ERROR_PROTOCOL = 48; // unsupported protocol + int BASS_ERROR_DENIED = 49; // access denied + int BASS_ERROR_UNKNOWN = -1; // some other mystery problem + + int BASS_ERROR_JAVA_CLASS = 500; // object class problem + + // BASS_SetConfig options + int BASS_CONFIG_BUFFER = 0; + int BASS_CONFIG_UPDATEPERIOD = 1; + int BASS_CONFIG_GVOL_SAMPLE = 4; + int BASS_CONFIG_GVOL_STREAM = 5; + int BASS_CONFIG_GVOL_MUSIC = 6; + int BASS_CONFIG_CURVE_VOL = 7; + int BASS_CONFIG_CURVE_PAN = 8; + int BASS_CONFIG_FLOATDSP = 9; + int BASS_CONFIG_3DALGORITHM = 10; + int BASS_CONFIG_NET_TIMEOUT = 11; + int BASS_CONFIG_NET_BUFFER = 12; + int BASS_CONFIG_PAUSE_NOPLAY = 13; + int BASS_CONFIG_NET_PREBUF = 15; + int BASS_CONFIG_NET_PASSIVE = 18; + int BASS_CONFIG_REC_BUFFER = 19; + int BASS_CONFIG_NET_PLAYLIST = 21; + int BASS_CONFIG_MUSIC_VIRTUAL = 22; + int BASS_CONFIG_VERIFY = 23; + int BASS_CONFIG_UPDATETHREADS = 24; + int BASS_CONFIG_DEV_BUFFER = 27; + int BASS_CONFIG_DEV_DEFAULT = 36; + int BASS_CONFIG_NET_READTIMEOUT = 37; + int BASS_CONFIG_HANDLES = 41; + int BASS_CONFIG_SRC = 43; + int BASS_CONFIG_SRC_SAMPLE = 44; + int BASS_CONFIG_ASYNCFILE_BUFFER = 45; + int BASS_CONFIG_OGG_PRESCAN = 47; + int BASS_CONFIG_DEV_NONSTOP = 50; + int BASS_CONFIG_VERIFY_NET = 52; + int BASS_CONFIG_DEV_PERIOD = 53; + int BASS_CONFIG_FLOAT = 54; + int BASS_CONFIG_NET_SEEK = 56; + int BASS_CONFIG_AM_DISABLE = 58; + int BASS_CONFIG_NET_PLAYLIST_DEPTH = 59; + int BASS_CONFIG_NET_PREBUF_WAIT = 60; + int BASS_CONFIG_ANDROID_SESSIONID = 62; + int BASS_CONFIG_ANDROID_AAUDIO = 67; + int BASS_CONFIG_SAMPLE_ONEHANDLE = 69; + int BASS_CONFIG_DEV_TIMEOUT = 70; + int BASS_CONFIG_NET_META = 71; + int BASS_CONFIG_NET_RESTRATE = 72; + int BASS_CONFIG_REC_DEFAULT = 73; + int BASS_CONFIG_NORAMP = 74; + + // BASS_SetConfigPtr options + int BASS_CONFIG_NET_AGENT = 16; + int BASS_CONFIG_NET_PROXY = 17; + int BASS_CONFIG_LIBSSL = 64; + int BASS_CONFIG_FILENAME = 75; + + int BASS_CONFIG_THREAD = 0x40000000; // flag: thread-specific setting + + // BASS_Init flags + int BASS_DEVICE_8BITS = 1; // unused + int BASS_DEVICE_MONO = 2; // mono + int BASS_DEVICE_3D = 4; // unused + int BASS_DEVICE_16BITS = 8; // limit output to 16-bit + int BASS_DEVICE_REINIT = 128; // reinitialize + int BASS_DEVICE_LATENCY = 0x100; // unused + int BASS_DEVICE_SPEAKERS = 0x800; // force enabling of speaker assignment + int BASS_DEVICE_NOSPEAKER = 0x1000; // ignore speaker arrangement + int BASS_DEVICE_DMIX = 0x2000; // use ALSA "dmix" plugin + int BASS_DEVICE_FREQ = 0x4000; // set device sample rate + int BASS_DEVICE_STEREO = 0x8000; // limit output to stereo + int BASS_DEVICE_AUDIOTRACK = 0x20000; // use AudioTrack output + int BASS_DEVICE_DSOUND = 0x40000; // use DirectSound output + int BASS_DEVICE_SOFTWARE = 0x80000; // disable hardware/fastpath output + + @Structure.FieldOrder({"name", "driver", "flags"}) + class BASS_DEVICEINFO extends Structure { + public String name; // description + public String driver; // driver + public int flags; + } + + // BASS_DEVICEINFO flags + int BASS_DEVICE_ENABLED = 1; + int BASS_DEVICE_DEFAULT = 2; + int BASS_DEVICE_INIT = 4; + + @Structure.FieldOrder({"flags", "hwsize", "hwfree", "freesam", "free3d", "minrate", "maxrate", "eax", "minbuf", "dsver", "latency", "initflags", "speakers", "freq"}) + class BASS_INFO extends Structure{ + public int flags; // device capabilities (DSCAPS_xxx flags) + public int hwsize; // unused + public int hwfree; // unused + public int freesam; // unused + public int free3d; // unused + public int minrate; // unused + public int maxrate; // unused + public int eax; // unused + public int minbuf; // recommended minimum buffer length in ms + public int dsver; // DirectSound version + public int latency; // average delay (in ms) before start of playback + public int initflags; // BASS_Init "flags" parameter + public int speakers; // number of speakers available + public int freq; // current output rate + } + + // Recording device info structure + @Structure.FieldOrder({"flags", "formats", "inputs", "singlein", "freq"}) + class BASS_RECORDINFO extends Structure { + public int flags; // device capabilities (DSCCAPS_xxx flags) + public int formats; // supported standard formats (WAVE_FORMAT_xxx flags) + public int inputs; // number of inputs + public boolean singlein; // TRUE = only 1 input can be set at a time + public int freq; // current input rate + } + + // Sample info structure + @Structure.FieldOrder({"freq", "chans", "flags", "length", "max", "origres", "chans", "mingap", "mode3d", "mindist", "maxdist", "iangle", "oangle", "outvol", "vam", "priority"}) + class BASS_SAMPLE extends Structure { + public int freq; // default playback rate + public float volume; // default volume (0-1) + public float pan; // default pan (-1=left, 0=middle, 1=right) + public int flags; // BASS_SAMPLE_xxx flags + public int length; // length (in bytes) + public int max; // maximum simultaneous playbacks + public int origres; // original resolution bits + public int chans; // number of channels + public int mingap; // minimum gap (ms) between creating channels + public int mode3d; // BASS_3DMODE_xxx mode + public float mindist; // minimum distance + public float maxdist; // maximum distance + public int iangle; // angle of inside projection cone + public int oangle; // angle of outside projection cone + public float outvol; // delta-volume outside the projection cone + public int vam; // unused + public int priority; // unused + } + + int BASS_SAMPLE_8BITS = 1; // 8 bit + int BASS_SAMPLE_FLOAT = 256; // 32-bit floating-point + int BASS_SAMPLE_MONO = 2; // mono + int BASS_SAMPLE_LOOP = 4; // looped + int BASS_SAMPLE_3D = 8; // 3D functionality + int BASS_SAMPLE_SOFTWARE = 16; // unused + int BASS_SAMPLE_MUTEMAX = 32; // mute at max distance (3D only) + int BASS_SAMPLE_VAM = 64; // unused + int BASS_SAMPLE_FX = 128; // unused + int BASS_SAMPLE_OVER_VOL = 0x10000; // override lowest volume + int BASS_SAMPLE_OVER_POS = 0x20000; // override longest playing + int BASS_SAMPLE_OVER_DIST = 0x30000; // override furthest from listener (3D only) + + int BASS_STREAM_PRESCAN = 0x20000; // scan file for accurate seeking and length + int BASS_STREAM_AUTOFREE = 0x40000; // automatically free the stream when it stops/ends + int BASS_STREAM_RESTRATE = 0x80000; // restrict the download rate of internet file streams + int BASS_STREAM_BLOCK = 0x100000; // download/play internet file stream in small blocks + int BASS_STREAM_DECODE = 0x200000; // don't play the stream, only decode (BASS_ChannelGetData) + int BASS_STREAM_STATUS = 0x800000; // give server status info (HTTP/ICY tags) in DOWNLOADPROC + + int BASS_MP3_IGNOREDELAY = 0x200; // ignore LAME/Xing/VBRI/iTunes delay & padding info + int BASS_MP3_SETPOS = BASS_STREAM_PRESCAN; + + int BASS_MUSIC_FLOAT = BASS_SAMPLE_FLOAT; + int BASS_MUSIC_MONO = BASS_SAMPLE_MONO; + int BASS_MUSIC_LOOP = BASS_SAMPLE_LOOP; + int BASS_MUSIC_3D = BASS_SAMPLE_3D; + int BASS_MUSIC_FX = BASS_SAMPLE_FX; + int BASS_MUSIC_AUTOFREE = BASS_STREAM_AUTOFREE; + int BASS_MUSIC_DECODE = BASS_STREAM_DECODE; + int BASS_MUSIC_PRESCAN = BASS_STREAM_PRESCAN; // calculate playback length + int BASS_MUSIC_CALCLEN = BASS_MUSIC_PRESCAN; + int BASS_MUSIC_RAMP = 0x200; // normal ramping + int BASS_MUSIC_RAMPS = 0x400; // sensitive ramping + int BASS_MUSIC_SURROUND = 0x800; // surround sound + int BASS_MUSIC_SURROUND2 = 0x1000; // surround sound (mode 2) + int BASS_MUSIC_FT2PAN = 0x2000; // apply FastTracker 2 panning to XM files + int BASS_MUSIC_FT2MOD = 0x2000; // play .MOD as FastTracker 2 does + int BASS_MUSIC_PT1MOD = 0x4000; // play .MOD as ProTracker 1 does + int BASS_MUSIC_NONINTER = 0x10000; // non-interpolated sample mixing + int BASS_MUSIC_SINCINTER = 0x800000; // sinc interpolated sample mixing + int BASS_MUSIC_POSRESET = 0x8000; // stop all notes when moving position + int BASS_MUSIC_POSRESETEX = 0x400000; // stop all notes and reset bmp/etc when moving position + int BASS_MUSIC_STOPBACK = 0x80000; // stop the music on a backwards jump effect + int BASS_MUSIC_NOSAMPLE = 0x100000; // don't load the samples + + // Speaker assignment flags + int BASS_SPEAKER_FRONT = 0x1000000; // front speakers + int BASS_SPEAKER_REAR = 0x2000000; // rear speakers + int BASS_SPEAKER_CENLFE = 0x3000000; // center & LFE speakers (5.1) + int BASS_SPEAKER_SIDE = 0x4000000; // side speakers (7.1) + static int BASS_SPEAKER_N(int n) { return n<<24; } // n'th pair of speakers (max 15) + int BASS_SPEAKER_LEFT = 0x10000000; // modifier: left + int BASS_SPEAKER_RIGHT = 0x20000000; // modifier: right + int BASS_SPEAKER_FRONTLEFT = BASS_SPEAKER_FRONT | BASS_SPEAKER_LEFT; + int BASS_SPEAKER_FRONTRIGHT = BASS_SPEAKER_FRONT | BASS_SPEAKER_RIGHT; + int BASS_SPEAKER_REARLEFT = BASS_SPEAKER_REAR | BASS_SPEAKER_LEFT; + int BASS_SPEAKER_REARRIGHT = BASS_SPEAKER_REAR | BASS_SPEAKER_RIGHT; + int BASS_SPEAKER_CENTER = BASS_SPEAKER_CENLFE | BASS_SPEAKER_LEFT; + int BASS_SPEAKER_LFE = BASS_SPEAKER_CENLFE | BASS_SPEAKER_RIGHT; + int BASS_SPEAKER_SIDELEFT = BASS_SPEAKER_SIDE | BASS_SPEAKER_LEFT; + int BASS_SPEAKER_SIDERIGHT = BASS_SPEAKER_SIDE | BASS_SPEAKER_RIGHT; + int BASS_SPEAKER_REAR2 = BASS_SPEAKER_SIDE; + int BASS_SPEAKER_REAR2LEFT = BASS_SPEAKER_SIDELEFT; + int BASS_SPEAKER_REAR2RIGHT = BASS_SPEAKER_SIDERIGHT; + + int BASS_ASYNCFILE = 0x40000000; // read file asynchronously + + int BASS_RECORD_PAUSE = 0x8000; // start recording paused + + // Channel info structure + @Structure.FieldOrder({"freq", "chans", "flags", "ctype", "origres", "plugin", "sample", "filename"}) + class BASS_CHANNELINFO extends Structure { + public int freq; // default playback rate + public int chans; // channels + public int flags; + public int ctype; // type of channel + public int origres; // original resolution + public int plugin; + public int sample; + public String filename; + } + + int BASS_ORIGRES_FLOAT = 0x10000; + + // BASS_CHANNELINFO types + int BASS_CTYPE_SAMPLE = 1; + int BASS_CTYPE_RECORD = 2; + int BASS_CTYPE_STREAM = 0x10000; + int BASS_CTYPE_STREAM_VORBIS = 0x10002; + int BASS_CTYPE_STREAM_OGG = 0x10002; + int BASS_CTYPE_STREAM_MP1 = 0x10003; + int BASS_CTYPE_STREAM_MP2 = 0x10004; + int BASS_CTYPE_STREAM_MP3 = 0x10005; + int BASS_CTYPE_STREAM_AIFF = 0x10006; + int BASS_CTYPE_STREAM_CA = 0x10007; + int BASS_CTYPE_STREAM_MF = 0x10008; + int BASS_CTYPE_STREAM_AM = 0x10009; + int BASS_CTYPE_STREAM_SAMPLE = 0x1000a; + int BASS_CTYPE_STREAM_DUMMY = 0x18000; + int BASS_CTYPE_STREAM_DEVICE = 0x18001; + int BASS_CTYPE_STREAM_WAV = 0x40000; // WAVE flag (LOWORD=codec) + int BASS_CTYPE_STREAM_WAV_PCM = 0x50001; + int BASS_CTYPE_STREAM_WAV_FLOAT = 0x50003; + int BASS_CTYPE_MUSIC_MOD = 0x20000; + int BASS_CTYPE_MUSIC_MTM = 0x20001; + int BASS_CTYPE_MUSIC_S3M = 0x20002; + int BASS_CTYPE_MUSIC_XM = 0x20003; + int BASS_CTYPE_MUSIC_IT = 0x20004; + int BASS_CTYPE_MUSIC_MO3 = 0x00100; // MO3 flag + + @Structure.FieldOrder({"ctype", "name", "exts"}) + class BASS_PLUGINFORM extends Structure { + int ctype; // channel type + String name; // format description + String exts; // file extension filter (*.ext1;*.ext2;etc...) + } + + @Structure.FieldOrder({"version", "formatc", "formats"}) + class BASS_PLUGININFO extends Structure { + int version; // version (same form as BASS_GetVersion) + int formatc; // number of formats + BASS_PLUGINFORM[] formats; // the array of formats + } + + // 3D vector (for 3D positions/velocities/orientations) + class BASS_3DVECTOR { + BASS_3DVECTOR() {} + BASS_3DVECTOR(float _x, float _y, float _z) { x=_x; y=_y; z=_z; } + float x; // +=right, -=left + float y; // +=up, -=down + float z; // +=front, -=behind + } + + // 3D channel modes + int BASS_3DMODE_NORMAL = 0; // normal 3D processing + int BASS_3DMODE_RELATIVE = 1; // position is relative to the listener + int BASS_3DMODE_OFF = 2; // no 3D processing + + // software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM) + int BASS_3DALG_DEFAULT = 0; + int BASS_3DALG_OFF = 1; + int BASS_3DALG_FULL = 2; + int BASS_3DALG_LIGHT = 3; + + // BASS_SampleGetChannel flags + int BASS_SAMCHAN_NEW = 1; // get a new playback channel + int BASS_SAMCHAN_STREAM = 2; // create a stream + + interface STREAMPROC extends Callback + { + int STREAMPROC(int handle, Pointer buffer, int length, Pointer user); + /* User stream callback function. + handle : The stream that needs writing + buffer : Buffer to write the samples in + length : Number of bytes to write + user : The 'user' parameter value given when calling BASS_StreamCreate + RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end + the stream. */ + } + + int BASS_STREAMPROC_END = 0x80000000; // end of user stream flag + + // Special STREAMPROCs + int STREAMPROC_DUMMY = 0; // "dummy" stream + int STREAMPROC_PUSH = -1; // push stream + int STREAMPROC_DEVICE = -2; // device mix stream + int STREAMPROC_DEVICE_3D = -3; // device 3D mix stream + + // BASS_StreamCreateFileUser file systems + int STREAMFILE_NOBUFFER = 0; + int STREAMFILE_BUFFER = 1; + int STREAMFILE_BUFFERPUSH = 2; + + interface BASS_FILEPROCS extends Callback + { + // User file stream callback functions + void FILECLOSEPROC(Pointer user); + long FILELENPROC(Pointer user) ; + int FILEREADPROC(Pointer buffer, int length, Pointer user); + boolean FILESEEKPROC(long offset, Pointer user); + } + + // BASS_StreamPutFileData options + int BASS_FILEDATA_END = 0; // end & close the file + + // BASS_StreamGetFilePosition modes + int BASS_FILEPOS_CURRENT = 0; + int BASS_FILEPOS_DECODE = BASS_FILEPOS_CURRENT; + int BASS_FILEPOS_DOWNLOAD = 1; + int BASS_FILEPOS_END = 2; + int BASS_FILEPOS_START = 3; + int BASS_FILEPOS_CONNECTED = 4; + int BASS_FILEPOS_BUFFER = 5; + int BASS_FILEPOS_SOCKET = 6; + int BASS_FILEPOS_ASYNCBUF = 7; + int BASS_FILEPOS_SIZE = 8; + int BASS_FILEPOS_BUFFERING = 9; + int BASS_FILEPOS_AVAILABLE = 10; + + interface DOWNLOADPROC extends Callback + { + void DOWNLOADPROC(Pointer buffer, int length, Pointer user); + /* Internet stream download callback function. + buffer : Buffer containing the downloaded data... NULL=end of download + length : Number of bytes in the buffer + user : The 'user' parameter value given when calling BASS_StreamCreateURL */ + } + + // BASS_ChannelSetSync types + int BASS_SYNC_POS = 0; + int BASS_SYNC_END = 2; + int BASS_SYNC_META = 4; + int BASS_SYNC_SLIDE = 5; + int BASS_SYNC_STALL = 6; + int BASS_SYNC_DOWNLOAD = 7; + int BASS_SYNC_FREE = 8; + int BASS_SYNC_SETPOS = 11; + int BASS_SYNC_MUSICPOS = 10; + int BASS_SYNC_MUSICINST = 1; + int BASS_SYNC_MUSICFX = 3; + int BASS_SYNC_OGG_CHANGE = 12; + int BASS_SYNC_DEV_FAIL = 14; + int BASS_SYNC_DEV_FORMAT = 15; + int BASS_SYNC_THREAD = 0x20000000; // flag: call sync in other thread + int BASS_SYNC_MIXTIME = 0x40000000; // flag: sync at mixtime, else at playtime + int BASS_SYNC_ONETIME = 0x80000000; // flag: sync only once, else continuously + + interface SYNCPROC extends Callback + { + void SYNCPROC(int handle, int channel, int data, Pointer user); + /* Sync callback function. + handle : The sync that has occured + channel: Channel that the sync occured in + data : Additional data associated with the sync's occurance + user : The 'user' parameter given when calling BASS_ChannelSetSync */ + } + + interface DSPPROC extends Callback + { + void DSPPROC(int handle, int channel, Pointer buffer, int length, Pointer user); + /* DSP callback function. + handle : The DSP handle + channel: Channel that the DSP is being applied to + buffer : Buffer to apply the DSP to + length : Number of bytes in the buffer + user : The 'user' parameter given when calling BASS_ChannelSetDSP */ + } + + interface RECORDPROC extends Callback + { + boolean RECORDPROC(int handle, Pointer buffer, int length, Pointer user); + /* Recording callback function. + handle : The recording handle + buffer : Buffer containing the recorded sample data + length : Number of bytes + user : The 'user' parameter value given when calling BASS_RecordStart + RETURN : true = continue recording, false = stop */ + } + + // BASS_ChannelIsActive return values + int BASS_ACTIVE_STOPPED = 0; + int BASS_ACTIVE_PLAYING =1; + int BASS_ACTIVE_STALLED = 2; + int BASS_ACTIVE_PAUSED = 3; + int BASS_ACTIVE_PAUSED_DEVICE = 4; + + // Channel attributes + int BASS_ATTRIB_FREQ = 1; + int BASS_ATTRIB_VOL = 2; + int BASS_ATTRIB_PAN = 3; + int BASS_ATTRIB_EAXMIX = 4; + int BASS_ATTRIB_NOBUFFER = 5; + int BASS_ATTRIB_VBR = 6; + int BASS_ATTRIB_CPU = 7; + int BASS_ATTRIB_SRC = 8; + int BASS_ATTRIB_NET_RESUME = 9; + int BASS_ATTRIB_SCANINFO = 10; + int BASS_ATTRIB_NORAMP = 11; + int BASS_ATTRIB_BITRATE = 12; + int BASS_ATTRIB_BUFFER = 13; + int BASS_ATTRIB_GRANULE = 14; + int BASS_ATTRIB_USER = 15; + int BASS_ATTRIB_TAIL = 16; + int BASS_ATTRIB_PUSH_LIMIT = 17; + int BASS_ATTRIB_DOWNLOADPROC = 18; + int BASS_ATTRIB_VOLDSP = 19; + int BASS_ATTRIB_VOLDSP_PRIORITY = 20; + int BASS_ATTRIB_MUSIC_AMPLIFY = 0x100; + int BASS_ATTRIB_MUSIC_PANSEP = 0x101; + int BASS_ATTRIB_MUSIC_PSCALER = 0x102; + int BASS_ATTRIB_MUSIC_BPM = 0x103; + int BASS_ATTRIB_MUSIC_SPEED = 0x104; + int BASS_ATTRIB_MUSIC_VOL_GLOBAL = 0x105; + int BASS_ATTRIB_MUSIC_VOL_CHAN = 0x200; // + channel # + int BASS_ATTRIB_MUSIC_VOL_INST = 0x300; // + instrument # + + // BASS_ChannelSlideAttribute flags + int BASS_SLIDE_LOG = 0x1000000; + + // BASS_ChannelGetData flags + int BASS_DATA_AVAILABLE = 0; // query how much data is buffered + int BASS_DATA_NOREMOVE = 0x10000000; // flag: don't remove data from recording buffer + int BASS_DATA_FIXED = 0x20000000; // unused + int BASS_DATA_FLOAT = 0x40000000; // flag: return floating-point sample data + int BASS_DATA_FFT256 = 0x80000000; // 256 sample FFT + int BASS_DATA_FFT512 = 0x80000001; // 512 FFT + int BASS_DATA_FFT1024 = 0x80000002; // 1024 FFT + int BASS_DATA_FFT2048 = 0x80000003; // 2048 FFT + int BASS_DATA_FFT4096 = 0x80000004; // 4096 FFT + int BASS_DATA_FFT8192 = 0x80000005; // 8192 FFT + int BASS_DATA_FFT16384 = 0x80000006; // 16384 FFT + int BASS_DATA_FFT32768 = 0x80000007; // 32768 FFT + int BASS_DATA_FFT_INDIVIDUAL = 0x10; // FFT flag: FFT for each channel, else all combined + int BASS_DATA_FFT_NOWINDOW = 0x20; // FFT flag: no Hanning window + int BASS_DATA_FFT_REMOVEDC = 0x40; // FFT flag: pre-remove DC bias + int BASS_DATA_FFT_COMPLEX = 0x80; // FFT flag: return complex data + int BASS_DATA_FFT_NYQUIST = 0x100; // FFT flag: return extra Nyquist value + + // BASS_ChannelGetLevelEx flags + int BASS_LEVEL_MONO = 1; // get mono level + int BASS_LEVEL_STEREO = 2; // get stereo level + int BASS_LEVEL_RMS = 4; // get RMS levels + int BASS_LEVEL_VOLPAN = 8; // apply VOL/PAN attributes to the levels + int BASS_LEVEL_NOREMOVE = 16; // don't remove data from recording buffer + + // BASS_ChannelGetTags types : what's returned + int BASS_TAG_ID3 = 0; // ID3v1 tags : TAG_ID3 + int BASS_TAG_ID3V2 = 1; // ID3v2 tags : ByteBuffer + int BASS_TAG_OGG = 2; // OGG comments : String array + int BASS_TAG_HTTP = 3; // HTTP headers : String array + int BASS_TAG_ICY = 4; // ICY headers : String array + int BASS_TAG_META = 5; // ICY metadata : String + int BASS_TAG_APE = 6; // APE tags : String array + int BASS_TAG_MP4 = 7; // MP4/iTunes metadata : String array + int BASS_TAG_VENDOR = 9; // OGG encoder : String + int BASS_TAG_LYRICS3 = 10; // Lyric3v2 tag : String + int BASS_TAG_WAVEFORMAT = 14; // WAVE format : ByteBuffer containing WAVEFORMATEEX structure + int BASS_TAG_AM_NAME = 16; // Android Media codec name : String + int BASS_TAG_ID3V2_2 = 17; // ID3v2 tags (2nd block) : ByteBuffer + int BASS_TAG_AM_MIME = 18; // Android Media MIME type : String + int BASS_TAG_LOCATION = 19; // redirected URL : String + int BASS_TAG_RIFF_INFO = 0x100; // RIFF "INFO" tags : String array + int BASS_TAG_RIFF_BEXT = 0x101; // RIFF/BWF "bext" tags : TAG_BEXT + int BASS_TAG_RIFF_CART = 0x102; // RIFF/BWF "cart" tags : TAG_CART + int BASS_TAG_RIFF_DISP = 0x103; // RIFF "DISP" text tag : String + int BASS_TAG_RIFF_CUE = 0x104; // RIFF "cue " chunk : TAG_CUE structure + int BASS_TAG_RIFF_SMPL = 0x105; // RIFF "smpl" chunk : TAG_SMPL structure + int BASS_TAG_APE_BINARY = 0x1000; // + index #, binary APE tag : TAG_APE_BINARY + int BASS_TAG_MUSIC_NAME = 0x10000; // MOD music name : String + int BASS_TAG_MUSIC_MESSAGE = 0x10001; // MOD message : String + int BASS_TAG_MUSIC_ORDERS = 0x10002; // MOD order list : ByteBuffer + int BASS_TAG_MUSIC_AUTH = 0x10003; // MOD author : UTF-8 string + int BASS_TAG_MUSIC_INST = 0x10100; // + instrument #, MOD instrument name : String + int BASS_TAG_MUSIC_CHAN = 0x10200; // + channel #, MOD channel name : String + int BASS_TAG_MUSIC_SAMPLE = 0x10300; // + sample #, MOD sample name : String + int BASS_TAG_BYTEBUFFER = 0x10000000; // flag: return a ByteBuffer instead of a String or TAG_ID3 + + // ID3v1 tag structure + @Structure.FieldOrder({"id", "title", "artist", "album", "year", "comment", "genre", "track"}) + class TAG_ID3 extends Structure { + String id; + String title; + String artist; + String album; + String year; + String comment; + byte genre; + byte track; + } + + // Binary APE tag structure + @Structure.FieldOrder({"key", "data", "length"}) + class TAG_APE_BINARY extends Structure { + String key; + Pointer data; + int length; + } + + // BASS_ChannelGetLength/GetPosition/SetPosition modes + int BASS_POS_BYTE = 0; // byte position + int BASS_POS_MUSIC_ORDER = 1; // order.row position, MAKELONG(order,row) + int BASS_POS_OGG = 3; // OGG bitstream number + int BASS_POS_END = 0x10; // trimmed end position + int BASS_POS_LOOP = 0x11; // loop start positiom + int BASS_POS_FLUSH = 0x1000000; // flag: flush decoder/FX buffers + int BASS_POS_RESET = 0x2000000; // flag: reset user file buffers + int BASS_POS_RELATIVE = 0x4000000; // flag: seek relative to the current position + int BASS_POS_INEXACT = 0x8000000; // flag: allow seeking to inexact position + int BASS_POS_DECODE = 0x10000000; // flag: get the decoding (not playing) position + int BASS_POS_DECODETO = 0x20000000; // flag: decode to the position instead of seeking + int BASS_POS_SCAN = 0x40000000; // flag: scan to the position + + // BASS_ChannelSetDevice/GetDevice option + int BASS_NODEVICE = 0x20000; + + // DX8 effect types, use with BASS_ChannelSetFX + int BASS_FX_DX8_CHORUS = 0; + int BASS_FX_DX8_COMPRESSOR = 1; + int BASS_FX_DX8_DISTORTION = 2; + int BASS_FX_DX8_ECHO = 3; + int BASS_FX_DX8_FLANGER = 4; + int BASS_FX_DX8_GARGLE = 5; + int BASS_FX_DX8_I3DL2REVERB = 6; + int BASS_FX_DX8_PARAMEQ = 7; + int BASS_FX_DX8_REVERB = 8; + int BASS_FX_VOLUME = 9; + + @Structure.FieldOrder({"fWetDryMix", "fDepth", "fFeedback", "fFrequency", "lWaveform", "fDelay", "lPhase"}) + class BASS_DX8_CHORUS extends Structure { + float fWetDryMix; + float fDepth; + float fFeedback; + float fFrequency; + int lWaveform; // 0=triangle, 1=sine + float fDelay; + int lPhase; // BASS_DX8_PHASE_xxx + } + + @Structure.FieldOrder({"fGain","fEdge","fPostEQCenterFrequency","fPostEQBandwidth","fPreLowpassCutoff"}) + class BASS_DX8_DISTORTION extends Structure { + float fGain; + float fEdge; + float fPostEQCenterFrequency; + float fPostEQBandwidth; + float fPreLowpassCutoff; + } + + @Structure.FieldOrder({"fWetDryMix","fFeedback","fLeftDelay","fRightDelay","lPanDelay"}) + class BASS_DX8_ECHO extends Structure { + float fWetDryMix; + float fFeedback; + float fLeftDelay; + float fRightDelay; + boolean lPanDelay; + } + + @Structure.FieldOrder({"fWetDryMix","fDepth","fFeedback","fFrequency","lWaveform","fDelay","lPhase"}) + class BASS_DX8_FLANGER extends Structure { + float fWetDryMix; + float fDepth; + float fFeedback; + float fFrequency; + int lWaveform; // 0=triangle, 1=sine + float fDelay; + int lPhase; // BASS_DX8_PHASE_xxx + } + + @Structure.FieldOrder({"fCenter","fBandwidth","fGain"}) + class BASS_DX8_PARAMEQ extends Structure { + float fCenter; + float fBandwidth; + float fGain; + } + + @Structure.FieldOrder({"fInGain","fReverbMix","fReverbTime","fHighFreqRTRatio"}) + class BASS_DX8_REVERB extends Structure { + float fInGain; + float fReverbMix; + float fReverbTime; + float fHighFreqRTRatio; + } + + int BASS_DX8_PHASE_NEG_180 = 0; + int BASS_DX8_PHASE_NEG_90 = 1; + int BASS_DX8_PHASE_ZERO = 2; + int BASS_DX8_PHASE_90 = 3; + int BASS_DX8_PHASE_180 = 4; + + @Structure.FieldOrder({"fTarget","fCurrent","fTime","lCurve"}) + class BASS_FX_VOLUME_PARAM extends Structure { + float fTarget; + float fCurrent; + float fTime; + int lCurve; + } + + class FloatValue { + public float value; + } + + boolean BASS_SetConfig(int option, int value); + int BASS_GetConfig(int option); + boolean BASS_SetConfigPtr(int option, Pointer value); + Object BASS_GetConfigPtr(int option); + int BASS_GetVersion(); + int BASS_ErrorGetCode(); + boolean BASS_GetDeviceInfo(int device, BASS_DEVICEINFO info); + boolean BASS_Init(int device, int freq, int flags); + boolean BASS_Free(); + boolean BASS_SetDevice(int device); + int BASS_GetDevice(); + boolean BASS_GetInfo(BASS_INFO info); + boolean BASS_Start(); + boolean BASS_Stop(); + boolean BASS_Pause(); + int BASS_IsStarted(); + boolean BASS_Update(int length); + float BASS_GetCPU(); + boolean BASS_SetVolume(float volume); + float BASS_GetVolume(); + + boolean BASS_Set3DFactors(float distf, float rollf, float doppf); + boolean BASS_Get3DFactors(FloatValue distf, FloatValue rollf, FloatValue doppf); + boolean BASS_Set3DPosition(BASS_3DVECTOR pos, BASS_3DVECTOR vel, BASS_3DVECTOR front, BASS_3DVECTOR top); + boolean BASS_Get3DPosition(BASS_3DVECTOR pos, BASS_3DVECTOR vel, BASS_3DVECTOR front, BASS_3DVECTOR top); + void BASS_Apply3D(); + + int BASS_PluginLoad(String file, int flags); + boolean BASS_PluginFree(int handle); + boolean BASS_PluginEnable(int handle, boolean enable); + BASS_PLUGININFO BASS_PluginGetInfo(int handle); + + int BASS_SampleLoad(String file, long offset, int length, int max, int flags); + int BASS_SampleLoad(Pointer file, long offset, int length, int max, int flags); + int BASS_SampleCreate(int length, int freq, int chans, int max, int flags); + boolean BASS_SampleFree(int handle); + boolean BASS_SampleSetData(int handle, Pointer buffer); + boolean BASS_SampleGetData(int handle, Pointer buffer); + boolean BASS_SampleGetInfo(int handle, BASS_SAMPLE info); + boolean BASS_SampleSetInfo(int handle, BASS_SAMPLE info); + int BASS_SampleGetChannel(int handle, boolean onlynew); + int BASS_SampleGetChannels(int handle, int[] channels); + boolean BASS_SampleStop(int handle); + + int BASS_StreamCreate(int freq, int chans, int flags, STREAMPROC proc, Pointer user); + int BASS_StreamCreateFile(boolean mem, String file, long offset, long length, int flags); + int BASS_StreamCreateFile(Pointer file, long offset, long length, int flags); + int BASS_StreamCreateURL(String url, int offset, int flags, DOWNLOADPROC proc, Pointer user); + int BASS_StreamCreateFileUser(int system, int flags, BASS_FILEPROCS procs, Pointer user); + boolean BASS_StreamFree(int handle); + long BASS_StreamGetFilePosition(int handle, int mode); + int BASS_StreamPutData(int handle, Pointer buffer, int length); + int BASS_StreamPutFileData(int handle, Pointer buffer, int length); + + int BASS_MusicLoad(String file, long offset, int length, int flags, int freq); + int BASS_MusicLoad(Pointer file, long offset, int length, int flags, int freq); + boolean BASS_MusicFree(int handle); + + boolean BASS_RecordGetDeviceInfo(int device, BASS_DEVICEINFO info); + boolean BASS_RecordInit(int device); + boolean BASS_RecordFree(); + boolean BASS_RecordSetDevice(int device); + int BASS_RecordGetDevice(); + boolean BASS_RecordGetInfo(BASS_RECORDINFO info); + String BASS_RecordGetInputName(int input); + boolean BASS_RecordSetInput(int input, int flags, float volume); + int BASS_RecordGetInput(int input, FloatValue volume); + int BASS_RecordStart(int freq, int chans, int flags, RECORDPROC proc, Pointer user); + + double BASS_ChannelBytes2Seconds(int handle, long pos); + long BASS_ChannelSeconds2Bytes(int handle, double pos); + int BASS_ChannelGetDevice(int handle); + boolean BASS_ChannelSetDevice(int handle, int device); + int BASS_ChannelIsActive(int handle); + boolean BASS_ChannelGetInfo(int handle, BASS_CHANNELINFO info); + Object BASS_ChannelGetTags(int handle, int tags); + long BASS_ChannelFlags(int handle, int flags, int mask); + boolean BASS_ChannelLock(int handle, boolean lock); + boolean BASS_ChannelFree(int handle); + boolean BASS_ChannelPlay(int handle, boolean restart); + boolean BASS_ChannelStart(int handle); + boolean BASS_ChannelStop(int handle); + boolean BASS_ChannelPause(int handle); + boolean BASS_ChannelUpdate(int handle, int length); + boolean BASS_ChannelSetAttribute(int handle, int attrib, float value); + boolean BASS_ChannelGetAttribute(int handle, int attrib, FloatValue value); + boolean BASS_ChannelSlideAttribute(int handle, int attrib, float value, int time); + boolean BASS_ChannelIsSliding(int handle, int attrib); + boolean BASS_ChannelSetAttributeEx(int handle, int attrib, Pointer value, int size); + boolean BASS_ChannelSetAttributeDOWNLOADPROC(int handle, DOWNLOADPROC proc, Pointer user); + int BASS_ChannelGetAttributeEx(int handle, int attrib, Pointer value, int size); + boolean BASS_ChannelSet3DAttributes(int handle, int mode, float min, float max, int iangle, int oangle, float outvol); + boolean BASS_ChannelGet3DAttributes(int handle, Integer mode, FloatValue min, FloatValue max, Integer iangle, Integer oangle, FloatValue outvol); + boolean BASS_ChannelSet3DPosition(int handle, BASS_3DVECTOR pos, BASS_3DVECTOR orient, BASS_3DVECTOR vel); + boolean BASS_ChannelGet3DPosition(int handle, BASS_3DVECTOR pos, BASS_3DVECTOR orient, BASS_3DVECTOR vel); + long BASS_ChannelGetLength(int handle, int mode); + boolean BASS_ChannelSetPosition(int handle, long pos, int mode); + long BASS_ChannelGetPosition(int handle, int mode); + int BASS_ChannelGetLevel(int handle); + boolean BASS_ChannelGetLevelEx(int handle, float[] levels, float length, int flags); + int BASS_ChannelGetData(int handle, Pointer buffer, int length); + int BASS_ChannelSetSync(int handle, int type, long param, SYNCPROC proc, Pointer user); + boolean BASS_ChannelRemoveSync(int handle, int sync); + boolean BASS_ChannelSetLink(int handle, int chan); + boolean BASS_ChannelRemoveLink(int handle, int chan); + int BASS_ChannelSetDSP(int handle, DSPPROC proc, Pointer user, int priority); + boolean BASS_ChannelRemoveDSP(int handle, int dsp); + int BASS_ChannelSetFX(int handle, int type, int priority); + boolean BASS_ChannelRemoveFX(int handle, int fx); + + boolean BASS_FXSetParameters(int handle, Object params); + boolean BASS_FXGetParameters(int handle, Object params); + boolean BASS_FXSetPriority(int handle, int priority); + boolean BASS_FXReset(int handle); + // gak bisa + int BASS_StreamCreate(int freq, int chans, int flags, int proc, Pointer user); + + + +} diff --git a/src/Audio/PlaybackEvent.java b/src/Audio/PlaybackEvent.java new file mode 100644 index 0000000..b41865f --- /dev/null +++ b/src/Audio/PlaybackEvent.java @@ -0,0 +1,8 @@ +package Audio; + +public interface PlaybackEvent { + void onPlaybackStart(AudioFileProperties prop); + void onPlaybackFinished(AudioFileProperties prop); + void onPlaybackFailure(AudioFileProperties prop, String reason); + void onPlaybackLooped(AudioFileProperties prop); +}