Core_Engine

Before Playback

Before Playback Step-1: initialize PDJE core engine

class PDJE

the main Interface of this Engine PDJE gets music data and track data from database. from that datas, you can activate music player and you can get a music player handler. with this player handler, you can control music’s mixing in real time.

to-use

  1. make PDJE object

  2. call SearchTrack

  3. call InitPlayer

  4. use player. this is handler.

digraph PDJE_Interface_Tree{ PDJE -> Search_Tools; PDJE -> Player; Player -> Player_ON_OFF; Player -> FXController; Player -> MusicController; FXController -> FX_ON_OFF; FXController -> FX_arg_setter; FX_arg_setter -> change_FX_value; MusicController -> Load_Music; MusicController -> Unload_Music; MusicController -> ON_OFF_Music; MusicController -> Cue_Music; MusicController -> FXController; }

auto engine = new PDJE("database/path");
PDJE engine = new PDJE("database/path");
import pdje_POLYGLOT as pypdje
engine = pypdje.PDJE("database/path")
var engine:PDJE_Wrapper = PDJE_Wrapper.new()
engine.InitEngine("res://database/path")

Before Playback Step-2: Search Music & Track

MUS_VEC PDJE::SearchMusic(const UNSANITIZED &Title, const UNSANITIZED &composer, const double bpm = -1)

searches musics and metadatas from database. if you don’t need to filter, send “” to the values

Parameters:
  • Title – the title of the music

  • composer – the composer of the music

  • bpm – the bpm of the music. send under zero to skip filter

Returns:

MUS_VEC

TRACK_VEC PDJE::SearchTrack(const UNSANITIZED &Title)

searches track the track contains the note data, mix data and included music lists.

Parameters:

Title – the title of the track. send “” to skip filter

Returns:

TRACK_VEC the array of the track_data. find what you want

trackdata td = engine->SearchTrack("Track name").front();
musdata md = engine->SearchMusic("music title", "composer name", -1.0).front();
//-1.0 means ignore bpm
TRACK_VEC tdvec = engine.SearchTrack("Track name");
MUS_VEC mdvec = engine.SearchMusic("music title", "composer name", -1.0);
//-1.0 means ignore bpm
import pdje_POLYGLOT as pypdje
from pdje_POLYGLOT import TRACK_VEC
from pdje_POLYGLOT import MUS_VEC

tdvec:TRACK_VEC = engine.SearchTrack("track name")
mdvec:MUS_VEC = engine.SearchMusic("music title", "composer name", -1.0)
#-1.0 means ignore bpm
var tdlist = engine.SearchTrack("track name")
var mdlist = engine.SearchMusic("music name", "composer name", -1.0)
#-1.0 means ignore bpm

Before Playback Step-3: Init, Activate & Deactivate Audio Player

bool PDJE::InitPlayer(PLAY_MODE mode, trackdata &td, const unsigned int FrameBufferSize)

this inits the music handler. the music handler called a “player” it initializes the player

Parameters:
  • mode – the play modes. you can choose “FULL_PRE_RENDER”, “HYBRID_RENDER”, “FULL_MANUAL_RENDER”

  • td – the track data. you can get this from SearchTrack()

  • FrameBufferSize – the buffersize. in this project, it uses 48000 samplerate. if you use 48 as a value, in theory, it calls mixing function 1000 times per second.

Returns:

true no error

Returns:

false error

bool audioPlayer::Activate()

Plays music.

inline void PDJE::ResetPlayer()

Reset the Player object.

bool audioPlayer::Deactivate()

Stops music.

bool player_OK = engine->InitPlayer(PLAY_MODE::HYBRID_RENDER, td, 48);
//render mode, trackdata, sample buffer

engine->ResetPlayer();
//reset player

bool activate_OK = engine->player->Activate();
//start playback

bool deactivate_OK = engine->player->Deactivate();
//stop playback
bool player_OK = engine.InitPlayer(PLAY_MODE.HYBRID_RENDER, tdvec[0], 48);
//render mode, trackdata, sample buffer

var AudioP = engine.GetPlayerObject();
//get player object

engine.ResetPlayer();
//reset player object.
//WARNING: after reset, AudioP becomes unavailable.

bool activate_OK = AudioP.Activate();
//start playback

bool deactivate_OK = AudioP.Deactivate();
//stop playback
from pdje_POLYGLOT import audioPlayer

player_OK = engine.InitPlayer(pyPDJE.HYBRID_RENDER, tdvec[0], 48)
#render mode, trackdata, sample buffer

AudioP:audioPlayer = engine.GetPlayerObject()
#get player object

engine.ResetPlayer()
#reset player object.
#WARNING: after reset, AudioP becomes unavailable.

activate_OK = AudioP.Activate()
#start playback

deactivate_OK = AudioP.Deactivate()
#stop playback
var player_OK = engine.InitPlayer(PDJE_Wrapper.HYBRID_RENDER, tdlist[0], 48)
#render mode, trackdata, sample buffer

var AudioP:PlayerWrapper = engine.GetPlayer()
#get player object

engine.ResetPlayer()
#reset player object.
#WARNING: after reset, AudioP becomes unavailable.

var activate_OK = AudioP.Activate()
#start playback

var deactivate_OK = AudioP.Deactivate()
#stop playback

On Playback

On Playback Step-1: Get & Use FX Controller Pannel

FXControlPannel *audioPlayer::GetFXControlPannel(const UNSANITIZED &title = "__PDJE__MAIN__")

fx controller getter this returns the fx controller. with this, you can control the fx in realtime manually.

Parameters:

title – the music to control. “__PDJE__MAIN__” means the prerendered music.

Returns:

FXControlPannel* but the “title” doesn’t exists, it returns nullptr.

void FXControlPannel::FX_ON_OFF(FXList fx, bool onoff)

activate/deactivate FX

Parameters:
  • fx – the fx type

  • onoff – activate / deactivate

enum FXList

the usable fx list

Values:

enumerator COMPRESSOR
enumerator DISTORTION
enumerator ECHO
enumerator EQ
enumerator FILTER
enumerator FLANGER
enumerator OCSFILTER
enumerator PANNER
enumerator PHASER
enumerator ROBOT
enumerator ROLL
enumerator TRANCE
enumerator VOL
ARGSETTER FXControlPannel::GetArgSetter(FXList fx)

Get the Arg Setter object.

Parameters:

fx – the fx type

Returns:

ARGSETTER the FX arg handler

bool FXControlPannel::checkSomethingOn()

check any FX is activated

Returns:

true , something is activated

Returns:

false , nothing activated.

to see Available args, See: FX_ARGS

FXControlPannel* fx_pannel = engine->player->GetFXControlPannel("title");
//get music's fx controller.

fx_pannel = engine->player->GetFXControlPannel();
//or get mixed track's fx controller like this.

bool TurnON = true;
fx_pannel->FX_ON_OFF(FXList::EQ, TurnON);
//turn on EQ effect

auto argsetter = fx_pannel->GetArgSetter(FXList::EQ);
for(auto& i : argsetter){
    std::cout << "fx key: " << i.first << std::endl;
}
// get argument setter for EQ
// you can check configurable (settable) arg keys like this

argsetter["EQSelect"](1);
argsetter["EQPower"](-32);
// change FX args by key
//for details, see FXArgs document
FXControlPannel fx_pannel = AudioP.GetFXControlPannel("title");
//get music's fx controller

fx_pannel = AudioP.GetFXControlPannel();
//or get mixed track's fx controller like this.

bool TurnON = true;
fx_pannel.FX_ON_OFF(FXList.EQ, TurnON);
//turn on EQ effect

ARGSETTER_WRAPPER argsetter = new ARGSETTER_WRAPPER(fx_pannel);
KEY_VEC keylist = argsetter.GetFXArgKeys(FXList.EQ);
foreach(var keys in keylist){
    Console.WriteLine(keys);
}
//get argument setter wrapper and get configurable arg keys like this.

argsetter.SetFXArg(FXList.EQ, "EQSelect", 1);
argsetter.SetFXArg(FXList.EQ, "EQPower", -32);

//change FX args by key
//for details, see FXArgs document
import pdje_POLYGLOT as pypdje
from pdje_POLYGLOT import FXControlPannel
from pdje_POLYGLOT import ARGSETTER_WRAPPER
from pdje_POLYGLOT import KEY_VEC

#...

fx_pannel:FXControlPannel = AudioP.GetFXControlPannel("title")
#get music's fx controller
fx_pannel = AudioP.GetFXControlPannel()
#or get mixed track's fx controller like this.
TurnON:bool = True
fx_pannel.FX_ON_OFF(pypdje.EQ, TurnON)
#turn on EQ effect
argsetter = ARGSETTER_WRAPPER(fx_pannel)
keylist:KEY_VEC = argsetter.GetFXArgKeys(pypdje.EQ)

for i in keylist:
    print("key: ", i)
#get argument setter wrapper and get configurable arg keys like this.

argsetter.SetFXArg(pypdje.EQ, "EQSelect", 1)
argsetter.SetFXArg(pypdje.EQ, "EQPower", -32)
#change FX args by key
#for details, see FXArgs document
var fx_pannel:FXControlPannel = AudioP.GetFXControlPannel()
#get mixed track's fx controller

var TurnON = true
fx_pannel.FX_ON_OFF(EnumWrapper.EQ, TurnON)
#turn on EQ effect

var argsetter:FXArgWrapper = fx_pannel.GetArgSetter()
print(argsetter.GetFXArgKeys(EnumWrapper.EQ))

#get argument setter wrapper and get configurable arg keys like this.

argsetter.SetFXArg(EnumWrapper.EQ, "EQSelect", 1)
argsetter.SetFXArg(EnumWrapper.EQ, "EQPower", -32)
#change FX args by key
#for details, see FXArgs document

On Playback Step-2: Get & Use Music Controller Pannel

class MusicControlPannel

Music handler for manual mode.

MusicControlPannel *audioPlayer::GetMusicControlPannel()

music controller getter this returns the music controller. with this, you can load music, stop music in realtime manually.

Returns:

MusicControlPannel* if something wrong, it returns nullptr.

bool MusicControlPannel::LoadMusic(litedb &ROOTDB, const musdata &Mus)

loads music to the deck. doesn’t play music

Parameters:

Mus – Searched music

Returns:

int, miniaudio Error code.

bool MusicControlPannel::SetMusic(const UNSANITIZED &title, const bool onOff)

turn on, off the music

Parameters:
  • title – the music title

  • onOff – True is on, False is off

Returns:

true

Returns:

false

bool MusicControlPannel::CueMusic(const UNSANITIZED &title, const unsigned long long newPos)

Change playback position of the music.

Parameters:
  • title – the music title

  • newPos – the new playback position of the music

Returns:

true

Returns:

false

LOADED_LIST MusicControlPannel::GetLoadedMusicList()

get music list on the deck

Returns:

LOADED_LIST

FXControlPannel *MusicControlPannel::getFXHandle(const UNSANITIZED &title)

gets FX handler

Parameters:

title – the title of the music

Returns:

FXControlPannel*, the handler pointer

auto musPannel = engine->player->GetMusicControlPannel();

auto musicFound = engine->SearchMusic("title", "composer");
//find music to playback manually

bool load_OK = musPannel->LoadMusic(*(engine->DBROOT), musicFound.front());
// load found music to deck. music won't playback in here

bool unload_OK = musPannel->UnloadMusic("title");
// unload music from deck. don't forget for the memory space.
// the deck always contains loaded music before calling musPannel.UnloadMusic or engine.ResetPlayer

bool onoff_OK = musPannel->SetMusic("title", true);
// turn on the music. now music playbacks

unsigned long long second = 15;
unsigned long long PCMFrame_position = 15 * 48000;
//PCMFrame_position = second X SampleRate

bool cue_OK = musPannel->CueMusic("title", PCMFrame_position);
//set playback position of the music.

std::vector<std::string> loaded_list = musPannel->GetLoadedMusicList();
//get loaded music list.

FXControlPannel* Fxhandle = musPannel->getFXHandle("title");
//get music's fx handle
MusicControlPannel musPannel = AudioP.GetMusicControlPannel();

var musicFound = engine.SearchMusic("title", "composer");
//find music to playback manually

bool load_OK = musPannel.LoadMusic(engine.DBROOT, musicFound[0]);
// load found music to deck. music won't playback in here

bool unload_OK = musPannel.UnloadMusic("title");
// unload music from deck. don't forget for the memory space.
// the deck always contains loaded music before calling musPannel.UnloadMusic or engine.ResetPlayer

bool onoff_OK = musPannel.SetMusic("title", true);
// turn on the music. now music playbacks

ulong second = 15;
ulong PCMFrame_position = 15 * 48000;
//PCMFrame_position = second X SampleRate

bool cue_OK = musPannel.CueMusic("title", PCMFrame_position);
//set playback position of the music.

KEY_VEC loaded_list = musPannel.GetLoadedMusicList();
//get loaded music list.

FXControlPannel Fxhandle = musPannel.getFXHandle("title");
//get music's fx handle
import pdje_POLYGLOT as pyPDJE
from pdje_POLYGLOT import MusicControlPannel
from pdje_POLYGLOT import FXControlPannel
from pdje_POLYGLOT import audioPlayer
from pdje_POLYGLOT import MUS_VEC

musPannel:MusicControlPannel = engine.player.GetMusicControlPannel()

musicFound:MUS_VEC = engine.SearchMusic("title", "composer")
#find music to playback manually

load_OK = musPannel.LoadMusic(engine.DBROOT, musicFound[0])
# load found music to deck. music won't playback in here

unload_OK = musPannel.UnloadMusic("title")
# unload music from deck. don't forget for the memory space.
# the deck always contains loaded music before calling musPannel.UnloadMusic or engine.ResetPlayer

onoff_OK = musPannel.SetMusic("title", True)
# turn on the music. now music playbacks

second:int = 15
PCMFrame_position:int = 15 * 48000
#PCMFrame_position = second X SampleRate

cue_OK = musPannel.CueMusic("title", PCMFrame_position)
#set playback position of the music.

loaded_list = musPannel.GetLoadedMusicList()
#get loaded music list.

Fxhandle:FXControlPannel = musPannel.getFXHandle("title")
#get music's fx handle
var musPannel:MusPannelWrapper = AudioP.GetMusicControlPannel()

var musicFound = engine.SearchMusic("title", "composer", -1.0)
#find music to playback manually

var load_OK = musPannel.LoadMusic("title", "composer", -1.0)
# load found music to deck. music won't playback in here

var unload_OK = musPannel.UnloadMusic("title")
# unload music from deck. don't forget for the memory space.
# the deck always contains loaded music before calling musPannel.UnloadMusic or engine.ResetPlayer

var onoff_OK = musPannel.SetMusic("title", true)
# turn on the music. now music playbacks

var second = 15
var PCMFrame_position = 15 * 48000
#PCMFrame_position = second X SampleRate

var cue_OK = musPannel.CueMusic("title", PCMFrame_position)
#set playback position of the music.

var loaded_list = musPannel.GetLoadedMusicList()
#get loaded music list.

var Fxhandle:FXWrapper = musPannel.getFXHandle("title")
#get music's fx handle

Editor API

The PDJE editor provides only an API and does not include a built-in graphical user interface (GUI).

With the editor API, you can:

  • Add audio files to the PDJE database (DB) and generate metadata

  • Create and edit mix sets (combinations of multiple tracks) using the registered music in the DB

  • Create and edit note data that can be used in rhythm games

Editor Step-1: Create & Manage DB

bool PDJE::InitEditor(const DONT_SANITIZE &auth_name, const DONT_SANITIZE &auth_email, const DONT_SANITIZE &projectRoot)

Initializes the editor.

Parameters:
  • auth_name – The author’s name for Git commits.

  • auth_email – The author’s email for Git commits.

  • projectRoot – The root directory of the editor project.

Returns:

true if the editor was initialized successfully, false otherwise.

inline void PDJE::CloseEditor()

Close the Editor object.

inline std::shared_ptr<editorObject> PDJE::GetEditorObject()

editor handler getter api for binded codes. this function gives you a editor handler.

Returns:

editorObject* the editor object. check nullptr before use.

DONT_SANITIZE editorObject::DESTROY_PROJECT()

Destroys the entire project.

Warning

This operation is irreversible.

Returns:

A string indicating the result of the operation.

bool initRes = engine->InitEditor("my name", "my@email, no need to fill", "ProjectRoot");
auto editor = engine->GetEditorObject();
std::string destroyRes = editor->DESTROY_PROJECT();
engine->CloseEditor();
bool initRes = engine.InitEditor("my name", "my@email, no need to fill", "ProjectRoot");
var editor = engine.GetEditorObject();
var destroyRes = engine.DESTROY_PROJECT();
engine.CloseEditor();
init_res = engine.InitEditor("my name", "my@email, no need to fill", "ProjectRoot")
editor:editorObject = engine.GetEditorObject()
destroy_res = editor.DESTROY_PROJECT()
engine.CloseEditor()
var init_res = engine.InitEditor("my name", "my@email, no need to fill", "ProjectRoot")
var editor = engine.GetEditor()
editor.DESTROY_PROJECT()
engine.CloseEditor()

Editor Step-2: Editing Control & History view

To see all functions, check Class editorObject

Undo

// Undo Mix
bool undoRes = editor->Undo<EDIT_ARG_MIX>();

// Undo Note
undoRes = editor->Undo<EDIT_ARG_NOTE>();

// Undo KV
undoRes = editor->Undo<EDIT_ARG_KEY_VALUE>();

// Undo Music
undoRes = editor->Undo<EDIT_ARG_MUSIC>();
bool undoRes = editor->UndoNote();
undoRes = editor->UndoMix();
undoRes = editor->UndoKV();
undoRes = editor->UndoMusic();
import pdje_POLYGLOT as pypdje
from pdje_POLYGLOT import editorObject
undoRes = editor.UndoNote()
undoRes = editor.UndoKV()
undoRes = editor.UndoMix()
undoRes = editor.UndoMusic()
var undoRes = editor.Undo(editor.NOTE, "")
undoRes = editor.Undo(editor.MUSIC, "music name")
undoRes = editor.Undo(editor.MIX, "")
undoRes = editor.Undo(editor.KV, "")

Redo

// Redo Mix
bool RedoRes = editor->Redo<EDIT_ARG_MIX>();

// Redo Note
RedoRes = editor->Redo<EDIT_ARG_NOTE>();

// Redo KV
RedoRes = editor->Redo<EDIT_ARG_KEY_VALUE>();

// Redo Music
RedoRes = editor->Redo<EDIT_ARG_MUSIC>();
bool RedoRes = editor->RedoNote();
RedoRes = editor->RedoMix();
RedoRes = editor->RedoKV();
RedoRes = editor->RedoMusic();
import pdje_POLYGLOT as pypdje
from pdje_POLYGLOT import editorObject
RedoRes = editor.RedoNote()
RedoRes = editor.RedoKV()
RedoRes = editor.RedoMix()
RedoRes = editor.RedoMusic()
var RedoRes = editor.Redo(editor.NOTE, "")
RedoRes = editor.Redo(editor.MUSIC, "music name")
RedoRes = editor.Redo(editor.MIX, "")
RedoRes = editor.Redo(editor.KV, "")

Time travel

To get necessary args, See Get edit logs

//get note edit logs
std::string logs = editor->GetLogWithJSONGraph<EDIT_ARG_NOTE>();
// std::string logs = editor->GetLogWithJSONGraph<EDIT_ARG_MIX>();
// std::string logs = editor->GetLogWithJSONGraph<EDIT_ARG_KEY_VALUE>();
// std::string logs = editor->GetLogWithJSONGraph<EDIT_ARG_MUSIC>("music name"); // this is the only difference

//parse json. try print them.
auto jj = nlohmann::json::parse(logs);

//the "BRANCH" has branch lists. this is json array.
std::string branchName = jj["BRANCH"].at(0)["NAME"];
std::string branch_head_oid = jj["BRANCH"].at(0)["OID"];
// "BRANCH" is an array of { "NAME": "...", "OID": "..." }
//it has two keys. "NAME", "OID". the oid means the head commit oid of the branch.

bool GoRes = editor->Go<EDIT_ARG_NOTE>(branchName, branch_head_oid);
//bool GoRes = editor->Go<EDIT_ARG_MIX>(branchName, branch_head_oid);
//bool GoRes = editor->Go<EDIT_ARG_KEY_VALUE>(branchName, branch_head_oid);
//bool GoRes = editor->Go<EDIT_ARG_MUSIC>(branchName, branch_head_oid);
//get logs
string logs = editor.GetLogMixJSON();
//string logs = editor.GetLogNoteJSON();
//string logs = editor.GetLogMusicJSON("music name");
//string logs = editor.GetLogKVJSON();

//get branch name, oid from logs

// editor.GoNote(name, oid);
editor.GoMix(name, oid);
// editor.GoKV(name, oid);
// editor.GoMusic(name, oid);
import pdje_POLYGLOT as pypdje
from pdje_POLYGLOT import editorObject

#...

logs = editor.GetLogMixJSON()
# logs = editor.GetLogKVJSON()
# logs = editor.GetLogMusicJSON("music name")
# logs = editor.GetLogNoteJSON()

# get branch name, oid from logs

# editor.GoKV(name, oid)
# editor.GoNote(name, oid)
# editor.GoMusic(name, oid)
editor.GoMix(name, oid)
var logs = editor.GetLogWithJSONGraph(editor.NOTE, "")
# var logs = editor.GetLogWithJSONGraph(editor.MUSIC, "music name")
# var logs = editor.GetLogWithJSONGraph(editor.KV, "")
# var logs = editor.GetLogWithJSONGraph(editor.MIX, "")

#get branch name, oid from logs

editor.Go(editor.NOTE, name, oid)
# editor.Go(editor.MUSIC, name, oid)
# editor.Go(editor.MIX, name, oid)
# editor.Go(editor.KV, name, oid)

Add line

See Mix Data first.

EDIT_ARG_MIX mixs;

mixs.type = TypeEnum::FILTER; //Filter
mixs.details = DetailEnum::LOW; //Low pass

mixs.ID = 1; //Deck number. access music with this.

mixs.first = ITPL_ENUM::ITPL_COSINE; // first arg
mixs.second = "5000,1000,2000,3000,4000,5000,5500,6000"; // second arg, eight point values
// mixs.first = ITPL_ENUM::ITPL_FLAT; // if no need interpolation
// mixs.second = "5000"; // just one value

mixs.third = "NONE"; // third arg

mixs.beat = 0;
mixs.subBeat = 0;
mixs.separate = 0;
//"start_position" = beat + (beat / separate) * subBeat

mixs.Ebeat = 16;//end beat
mixs.EsubBeat = 2;//end subBeat
mixs.Eseparate = 4;//end separate
//"end_position" = ebeat + (ebeat / eseparate) * esubBeat

//summation: add low pass filter from "start_position" to "end_position" with interpolation

editor->AddLine(mixs);//add mix data

// EDIT_ARG_NOTE data;
// EDIT_ARG_KEY_VALUE data;
// EDIT_ARG_MUSIC data;

// editor->AddLine(data);

// editor->AddLine("music name", "48000") // this changes the music's first beat position
EDIT_ARG_MIX mixs = new EDIT_ARG_MIX();

engine.editor.AddLineMix(mixs);


mixs.type = TypeEnum.FILTER; //Filter
mixs.details = DetailEnum.LOW; //Low pass

mixs.ID = 1; //Deck number. access music with this.

mixs.first = ITPL_ENUM.ITPL_COSINE.ToString(); // first arg
mixs.second = "5000,1000,2000,3000,4000,5000,5500,6000"; // second arg, eight point values
// mixs.first = ITPL_ENUM.ITPL_FLAT.ToString(); // if no need interpolation
// mixs.second = "5000"; // just one value

mixs.third = "NONE"; // third arg

mixs.beat = 0;
mixs.subBeat = 0;
mixs.separate = 0;
//"start_position" = beat + (beat / separate) * subBeat

mixs.Ebeat = 16;//end beat
mixs.EsubBeat = 2;//end subBeat
mixs.Eseparate = 4;//end separate
//"end_position" = ebeat + (ebeat / eseparate) * esubBeat

//summation: add low pass filter from "start_position" to "end_position" with interpolation

engine.editor.AddLineMix(mixs);//add mix data
// EDIT_ARG_NOTE data;
// editor.AddLineNote(data);

// EDIT_ARG_KEY_VALUE data;
// editor.AddLineKV(data);

// EDIT_ARG_MUSIC data;
// editor.AddLineMusic(data);

// editor.AddLine("music name", "48000"); // this changes the music's first beat position.
import pdje_POLYGLOT as pypdje

from pdje_POLYGLOT import EDIT_ARG_MIX
from pdje_POLYGLOT import EDIT_ARG_MUSIC
from pdje_POLYGLOT import EDIT_ARG_KEY_VALUE

from pdje_POLYGLOT import EDIT_ARG_NOTE
from pdje_POLYGLOT import editorObject

mixs = EDIT_ARG_MIX()

editor.AddLineMix(mixs)

pypdje.TypeEnum_BATTLE_DJ


mixs.type = pypdje.TypeEnum_FILTER #Filter
mixs.details = pypdje.DetailEnum_LOW #Low pass

mixs.ID = 1 #Deck number. access music with this.

mixs.first = pypdje.ITPL_COSINE.ToString() # first arg
mixs.second = "5000,1000,2000,3000,4000,5000,5500,6000" # second arg, eight point values
# mixs.first = pypdje.ITPL_FLAT.ToString() # if no need interpolation
# mixs.second = "5000" # just one value

mixs.third = "NONE" # third arg

mixs.beat = 0
mixs.subBeat = 0
mixs.separate = 0
#"start_position" = beat + (beat / separate) * subBeat

mixs.Ebeat = 16#end beat
mixs.EsubBeat = 2#end subBeat
mixs.Eseparate = 4#end separate
#"end_position" = ebeat + (ebeat / eseparate) * esubBeat

#summation: add low pass filter from "start_position" to "end_position" with interpolation

editor.AddLineMix(mixs)#add mix data
# data = EDIT_ARG_NOTE()
# editor.AddLineNote(data)

# data = EDIT_ARG_KEY_VALUE()
# editor.AddLineKV(data)

# data = EDIT_ARG_MUSIC()
# editor.AddLineMusic(data)

# editor.AddLine("music name", "48000") # this changes the music's first beat position.
var engine:PDJE_Wrapper = PDJE_Wrapper.new()
engine.InitEngine("res://database/path")

Get all lines

std::vector<EDIT_ARG_MIX> mixFound;
editor->getAll([&mixFound](const EDIT_ARG_MIX& mix_arg){//single threaded. will add multithreaded , faster getter soon.
    if(mix_arg.beat < 50){
        mixFound.push_back();
    }
});

// std::vector<EDIT_ARG_NOTE> Found;
// editor->getAll([&Found](const EDIT_ARG_NOTE& arg);

// std::vector<EDIT_ARG_KEY_VALUE> Found;
// editor->getAll([&Found](const EDIT_ARG_KEY_VALUE& arg);

// std::vector<EDIT_ARG_MUSIC> Found;
// editor->getAll([&Found](const EDIT_ARG_MUSIC& arg);
MixCall caller = new MixCall();

editor.GetAllMixes(caller);

// editor.GetAllKeyValues(caller);
// editor.GetAllMusics(caller);
// editor.GetAllNotes(caller);

public class MixCall : MixVisitor { // MusicVisitor, NoteVisitor, KVVisitor
    public List<EDIT_ARG_MIX> mixs = new List<EDIT_ARG_MIX>();
    public override void on_item(EDIT_ARG_MIX o)// override this function
    {
        if (o.beat > 50)
        {
            mixs.Add(o);
        }
    }
};// Just change MIX into NOTE, KEY_VALUE, MUSIC
import pdje_POLYGLOT as pypdje

class MixCall(pypdje.MixVisitor):# MusicVisitor, NoteVisitor, KVVisitor
    def __init__(self):
        super().__init__()
        self.mixs = []

    def on_item(self, o:EDIT_ARG_MIX):# def this function
        if o.beat > 50:
            self.mixs.append(o)

caller = MixCall()

editor.GetAllMixes(caller)

# editor.GetAllKeyValues(caller)
# editor.GetAllMusics(caller)
# editor.GetAllNotes(caller)

for i in caller.mixs:
    print(i)
var engine:PDJE_Wrapper = PDJE_Wrapper.new()
engine.InitEngine("res://database/path")

Delete line

std::vector<EDIT_ARG_NOTE> noteFound;

//find delete targets with getAll function.

for(const auto& delete_target : noteFound){
    editor->deleteLine(delete_target);
}

std::vector<EDIT_ARG_MIX> mixFound;

//find delete targets with getAll function.

bool skipType = true;
bool skipDetail = false;
for(const auto& delete_target : mixFound){
    editor->deleteLine(delete_target, skipType, skipDetail); //mix arg is special.
}
MixCall caller = new MixCall();

editor.GetAllMixes(caller);
bool skipType = true;
bool skipDetail = false;
foreach (var target in caller.mixs)
{
    editor.deleteLine(target, skipType, skipDetail);
    // editor.deleteLineKV(target);
    // editor.deleteLineMusic(target);
    // editor.deleteLineNote(target);
}
class MixCall(pypdje.MixVisitor):
    def __init__(self):
        super().__init__()
        self.mixs = []

    def on_item(self, o:EDIT_ARG_MIX):
        if o.beat > 50:
            self.mixs.append(o)

caller = MixCall()

editor.GetAllMixes(caller)

skip_type = False
skip_detail = True

for i in caller.mixs:
    editor.deleteLine(i, skip_type, skip_detail)
    # editor.deleteLineKV(i)
    # editor.deleteLineMusic(i)
    # editor.deleteLineNote(i)
var engine:PDJE_Wrapper = PDJE_Wrapper.new()
engine.InitEngine("res://database/path")

Get edit logs

/*
JSON structure produced:

{
"BRANCH": [                          // branch head list
    {
    "NAME": string,                  // branch name (e.g., "main")
    "OID":  string                   // head commit oid (40-hex from git_oid_tostr_s)
    },
    ...
],
"COMMIT": [                          // commit metadata list
    {
    "OID":      string,              // commit oid (40-hex)
    "EMAIL":    string,              // author email
    "NAME":     string,              // author name
    "PARENTID": string               // parent commit oid (may be empty/zero for initial)
    },
    ...
]
}
*/
std::string mix_json_graph = editor->GetLogWithJSONGraph<EDIT_ARG_MIX>();
std::string key_value_json_graph = editor->GetLogWithJSONGraph<EDIT_ARG_KEY_VALUE>();
std::string note_json_graph = editor->GetLogWithJSONGraph<EDIT_ARG_NOTE>();
std::string music_json_graph = editor->GetLogWithJSONGraph<EDIT_ARG_MUSIC>("music name");
/*
JSON structure produced:

{
"BRANCH": [                          // branch head list
    {
    "NAME": string,                  // branch name (e.g., "main")
    "OID":  string                   // head commit oid (40-hex from git_oid_tostr_s)
    },
    ...
],
"COMMIT": [                          // commit metadata list
    {
    "OID":      string,              // commit oid (40-hex)
    "EMAIL":    string,              // author email
    "NAME":     string,              // author name
    "PARENTID": string               // parent commit oid (may be empty/zero for initial)
    },
    ...
]
}
*/
string KV_json_graph = editor.GetLogKVJSON();
string Mix_json_graph = editor.GetLogMixJSON();
string Music_json_graph = editor.GetLogMusicJSON("music name");
string Note_json_graph = editor.GetLogNoteJSON();
"""
JSON structure produced:

{
"BRANCH": [                          // branch head list
    {
    "NAME": string,                  // branch name (e.g., "main")
    "OID":  string                   // head commit oid (40-hex from git_oid_tostr_s)
    },
    ...
],
"COMMIT": [                          // commit metadata list
    {
    "OID":      string,              // commit oid (40-hex)
    "EMAIL":    string,              // author email
    "NAME":     string,              // author name
    "PARENTID": string               // parent commit oid (may be empty/zero for initial)
    },
    ...
]
}
"""
KV_json_graph = editor.GetLogKVJSON()
Mix_json_graph = editor.GetLogMixJSON()
Music_json_graph = editor.GetLogMusicJSON("music name")
Note_json_graph = editor.GetLogNoteJSON()
var engine:PDJE_Wrapper = PDJE_Wrapper.new()
engine.InitEngine("res://database/path")

Update edit logs

auto engine = new PDJE("database/path");
PDJE engine = new PDJE("database/path");
import pdje_POLYGLOT as pypdje
engine = pypdje.PDJE("database/path")
var engine:PDJE_Wrapper = PDJE_Wrapper.new()
engine.InitEngine("res://database/path")