diff --git a/src/Main.kt b/src/Main.kt index 426288a..b80a605 100644 --- a/src/Main.kt +++ b/src/Main.kt @@ -1,21 +1,24 @@ +import audio.AudioFileInfo import audio.AudioPlayer import barix.BarixConnection import barix.TCP_Barix_Command_Server import codes.Somecodes.Companion.Get_ANN_ID import codes.Somecodes.Companion.IsAlphabethic import codes.Somecodes.Companion.IsNumber +import codes.Somecodes.Companion.Make_WAV_FileName +import codes.Somecodes.Companion.SoundbankResult_directory import codes.Somecodes.Companion.ValidFile import codes.Somecodes.Companion.ValidString import codes.Somecodes.Companion.dateformat1 import codes.Somecodes.Companion.timeformat2 import com.sun.jna.Platform import content.Category -import content.ContentCache import content.Language import content.ScheduleDay import content.VoiceType import database.MariaDB import database.Messagebank +import database.Soundbank import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -42,7 +45,6 @@ fun main() { Logger.info { "Starting AAS New Generation version $version" } val audioPlayer = AudioPlayer(44100) // 44100 Hz sampling rate audioPlayer.InitAudio(1) - val content = ContentCache() val db = MariaDB() // Coroutine untuk cek Paging Queue dan AAS Queue setiap detik @@ -114,12 +116,79 @@ fun main() { return mb_list } + /** + * Find Soundbank path for AlphabetNumeric category based on value + * @param sb List of Soundbank to search + * @param value String value to search, can be combination of letters and numbers, e.g. A1, B2, 3C, 12, etc. + * @return Soundbank path if found and valid, null if not found or invalid + */ + fun Get_Soundbank_AlpabethNumeric(sb: List, value: String): List? { + val result = mutableListOf() + if (ValidString(value)) { + if (sb.isNotEmpty()) { + val regex = Regex("([A-Z])?(\\d+)([A-Z])?") + val match = regex.find(value) + match?.groupValues?.forEach { + if (IsNumber(it)) { + val num = + sb.firstOrNull { s1 -> s1.Category == Category.AlphabetNumeric.name && s1.TAG == "N$it" } + if (num != null) { + if (ValidFile(num.Path)) { + result.add(num.Path) + } + } + } else if (IsAlphabethic(it)) { + val alp = + sb.firstOrNull { s1 -> s1.Category == Category.AlphabetNumeric.name && s1.TAG == it } + if (alp != null) { + if (ValidFile(alp.Path)) { + result.add(alp.Path) + } + } + } + } + if (result.isNotEmpty()) { + return result + } + } + } + return null + } + + val SoundbankKeywords = listOf("ANN_ID","AL","FLNUM","A_D","I_D","ORIGIN","CITY","SHALAT","PLACES","DESTINATION","ETAD","STANDCODE","GATECODE","REMARK","BCB","PLATNOMOR","REASON","PROCEDURE") + + /** + * Parse soundbank data from string value in format "KEY:VALUE KEY:VALUE ..." + * @param value String value to parse + * @return Map of key-value pairs if valid, null if invalid + */ + fun Get_Soundbank_Data(value: String) : Map? { + if (ValidString(value)){ + val values = value.split(" ").map { it.trim() }.filter { ValidString(it) } + if (values.isNotEmpty()){ + val result = mutableMapOf() + values.forEach { + val kv = it.split(":") + if (kv.size==2){ + val key = kv[0].trim().uppercase() + val val1 = kv[1].trim().uppercase() + if (ValidString(key) && ValidString(val1)){ + if (SoundbankKeywords.contains(key)) result[key] = val1 + } + } + } + if (result.isNotEmpty()) return result + } + } + return null + } + /** * Find soundbank files from messagebank tags, filtered by VoiceType and Language * @param mb Messagebank object * @param variables Map of variables to replace in tags. * @param cbOK Callback function if success, returns List of soundbank file names - * @param cbFail Callback function if fail, returns error message + * @param cbFail Callback function if failed, returns error message */ fun Get_Soundbank_Files( mb: Messagebank, @@ -144,38 +213,204 @@ fun main() { val files = mutableListOf() tags.forEach { tag -> - val _tag = tag.trim() - when (_tag) { + when (val _tag = tag.trim()) { "[AIRPLANE_NAME]" -> { + val value = variables["AIRPLANE_NAME"].orEmpty() + if (ValidString(value)) { + val airplane = + sb.firstOrNull { it.Category == Category.Airplane_Name.name && it.TAG == value } + if (airplane != null) { + if (ValidFile(airplane.Path)) { + files.add(airplane.Path) + } else { + cbFail.accept("Invalid soundbank file ${airplane.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("No Airplane_Name found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("AIRPLANE_NAME variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") + return + } } "[FLIGHT_NUMBER]" -> { + val alcode = variables["AIRPLANE_NAME"].orEmpty() + val fncode = variables["FLIGHT_NUMBER"].orEmpty() + if (ValidString(alcode) && ValidString(fncode)) { + val val1 = sb.firstOrNull { it.Category == Category.Airline_Code.name && it.TAG == alcode } + val val2 = Get_Soundbank_AlpabethNumeric(sb, fncode) + if (val1 != null) { + if (ValidFile(val1.Path)) { + files.add(val1.Path) + } else { + cbFail.accept("Invalid soundbank file ${val1.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("No Airline_Code found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + if (val2 != null && val2.isNotEmpty()) { + files.addAll(val2) + } else { + cbFail.accept("No valid soundbank files found for FLIGHT_NUMBER value '$fncode' for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + + } else { + cbFail.accept("AIRPLANE_NAME or FLIGHT_NUMBER variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") + return + } } "[PLATNOMOR]" -> { - + // plat nomor bisa huruf dan angka, atau huruf angka huruf, misalnya B123CD, AB1234EF, RI1 + val value = variables["PLATNOMOR"].orEmpty() + if (ValidString(value)) { + val regex = Regex("([A-Z]+)(\\d+)([A-Z]*)") + val match = regex.find(value) + if (match != null) { + val depan = match.groups[1]?.value // huruf depan + val tengah = match.groups[2]?.value // angka + val belakang = match.groups[3]?.value // huruf belakang, bisa kosong + // ambilin per huruf + depan?.forEach { + val dep = Get_Soundbank_AlpabethNumeric(sb, it.toString()) + if (dep != null) { + files.addAll(dep) + } + } + // ambilin per angka + tengah?.forEach { + val tgh = Get_Soundbank_AlpabethNumeric(sb, it.toString()) + if (tgh != null) { + files.addAll(tgh) + } + } + // ambilin per huruf + belakang?.forEach { + val blk = Get_Soundbank_AlpabethNumeric(sb, it.toString()) + if (blk != null) { + files.addAll(blk) + } + } + } else { + cbFail.accept("PLATNOMOR variable has invalid format for value '$value' in messagebank id ${mb.ANN_ID}") + return + } + } else { + cbFail.accept("PLATNOMOR variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") + return + } } "[CITY]" -> { - + val values = variables["CITY"].orEmpty().split(";").map { it.trim() }.filter { ValidString(it) } + if (values.isNotEmpty()) { + values.forEach { vv -> + val city = sb.firstOrNull { it.Category == Category.City.name && it.TAG == vv } + if (city != null) { + if (ValidFile(city.Path)) { + files.add(city.Path) + } else { + cbFail.accept("Invalid soundbank file ${city.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("No City found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } + } else { + cbFail.accept("CITY variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") + return + } } "[PLACES]" -> { + val value = variables["PLACES"].orEmpty() + if (ValidString(value)) { + val places = sb.firstOrNull { it.Category == Category.Places.name && it.TAG == value } + if (places != null) { + if (ValidFile(places.Path)) { + files.add(places.Path) + } else { + cbFail.accept("Invalid soundbank file ${places.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("No Places found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("PLACES variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") + return + } } "[ETAD]" -> { + val values = variables["ETAD"].orEmpty().split(":").map { it.trim() }.filter { IsNumber(it) } + if (values.size == 2) { + val hh = Get_Soundbank_AlpabethNumeric(sb, values[0]) + val mm = Get_Soundbank_AlpabethNumeric(sb, values[1]) + if (hh != null && mm != null && hh.isNotEmpty() && mm.isNotEmpty()) { + if (ValidFile(hh[0]) && ValidFile(mm[0])) { + files.add(hh[0]) + files.add(mm[0]) + } else { + cbFail.accept("ETAD variable has invalid soundbank files for tag $_tag in messagebank id ${mb.ANN_ID}, unable to find valid soundbank files for HH='${values[0]}' or MM='${values[1]}'") + return + } + } else { + cbFail.accept("ETAD variable has invalid soundbank for tag $_tag in messagebank id ${mb.ANN_ID}, unable to find soundbank for HH='${values[0]}' or MM='${values[1]}'") + return + } + } else { + cbFail.accept("ETAD variable has invalid format for tag $_tag in messagebank id ${mb.ANN_ID}, expected format HH:MM") + return + } } "[SHALAT]" -> { + val value = variables["SHALAT"].orEmpty() + if (ValidString(value)) { + val shalat = sb.firstOrNull { it.Category == Category.Shalat.name && it.TAG == value } + if (shalat != null) { + if (ValidFile(shalat.Path)) { + files.add(shalat.Path) + } else { + cbFail.accept("Invalid soundbank file ${shalat.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("No Shalat found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } + } else { + cbFail.accept("SHALAT variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") + return + } } "[BCB]" -> { - + // BCB bisa angka saja, misalnya 1,2,3 + // atau huruf dan angka, misalnya A1, B2, C3, 1A, 2B, 3C + val value = variables["BCB"].orEmpty() + val path = Get_Soundbank_AlpabethNumeric(sb, value) + if (path != null) { + files.addAll(path) + } else { + cbFail.accept("BCB variable is missing, empty, or doesn't have valid soundbank for value '$value' in messagebank id ${mb.ANN_ID}") + return + } } "[GATENUMBER]" -> { @@ -184,17 +419,16 @@ fun main() { val value = variables["GATENUMBER"].orEmpty() if (ValidString(value)) { val values = value.split(",").map { it.trim() }.filter { ValidString(it) } - if (values.isNotEmpty()){ - values.forEach { - if (IsNumber(it)){ - // gate number hanya angka + if (values.isNotEmpty()) { + values.forEach { vv -> + val path = Get_Soundbank_AlpabethNumeric(sb, vv) + if (path != null) { + files.addAll(path) } else { - // gate number gabungan huruf dan angka - val regex = Regex("([A-Z])?(\\d+)([A-Z])?") - + cbFail.accept("GATENUMBER variable doesn't have valid soundbank for value '$vv' in messagebank id ${mb.ANN_ID}") + return } } - } else { cbFail.accept("GATENUMBER variable is empty after split for tag $_tag in messagebank id ${mb.ANN_ID}") return @@ -207,33 +441,47 @@ fun main() { } "[REASON]" -> { - val reason = sb.firstOrNull { it.Category == Category.Reason.name && it.TAG == _tag } - if (reason != null) { - if (ValidFile(reason.Path)) { - files.add(reason.Path) + val value = variables["REASON"].orEmpty() + if (ValidString(value)) { + val reason = sb.firstOrNull { it.Category == Category.Reason.name && it.TAG == value } + if (reason != null) { + if (ValidFile(reason.Path)) { + files.add(reason.Path) + } else { + cbFail.accept("Invalid soundbank file ${reason.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } } else { - cbFail.accept("Invalid soundbank file ${reason.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + cbFail.accept("No Reason found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") return } } else { - cbFail.accept("No Reason found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + cbFail.accept("REASON variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") return } + } "[PROCEDURE]" -> { - val procedure = sb.firstOrNull { it.Category == Category.Procedure.name && it.TAG == _tag } - if (procedure != null) { - if (ValidFile(procedure.Path)) { - files.add(procedure.Path) + val value = variables["PROCEDURE"].orEmpty() + if (ValidString(value)) { + val procedure = sb.firstOrNull { it.Category == Category.Procedure.name && it.TAG == value } + if (procedure != null) { + if (ValidFile(procedure.Path)) { + files.add(procedure.Path) + } else { + cbFail.accept("Invalid soundbank file ${procedure.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + return + } } else { - cbFail.accept("Invalid soundbank file ${procedure.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + cbFail.accept("No Procedure found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") return } } else { - cbFail.accept("No Procedure found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}") + cbFail.accept("PROCEDURE variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}") return } + } else -> { @@ -255,6 +503,8 @@ fun main() { } } + // all tags processed, return files + cbOK.accept(files) } @@ -296,7 +546,62 @@ fun main() { // shalat, ambil messagebank berdasarkan ann_id dengan bahasa Indonesia saja Get_MessageBank_by_id(ann_id, listOf(Language.INDONESIA.name)).let { mblist -> if (mblist.isNotEmpty()) { - //TODO find soundbank + Get_Soundbank_Files( + mblist[0], + emptyMap(), + { + // dapat list dari files dan sudah dicek valid path + listfile -> + val listafi = mutableListOf() + listfile.forEach { filenya -> + val afi = audioPlayer.LoadAudioFile(filenya) + if (afi.isValid()) { + listafi.add(afi) + } + } + val targetfile = SoundbankResult_directory.resolve( + Make_WAV_FileName( + "Shalat", + "" + ) + ).toString() + audioPlayer.WavWriter( + listafi, + targetfile + ) { success, message -> + db.Add_Log("AAS", message) + if (success) { + // file siap broadcast + val targetafi = audioPlayer.LoadAudioFile(targetfile) + if (targetafi.isValid()) { + zz.forEach { z1 -> + StreamerOutputs.values.find { it.channel == z1 } + ?.SendData( + targetafi.bytes, + { db.Add_Log("AAS", it) }, + { db.Add_Log("AAS", it) }) + } + val logmsg = + "Broadcast started SHALAT message with generated file '$targetfile' to zones: ${qp.BroadcastZones}" + Logger.info { logmsg } + db.Add_Log("AAS", logmsg) + db.Delete_Queue_Paging_by_index(qp.index) + } else { + db.Add_Log( + "AAS", + "Failed to load generated Shalat WAV file $targetfile" + ) + } + } + } + + + }, + { err -> + db.Delete_Queue_Paging_by_index(qp.index) + db.Add_Log("AAS", err) + } + ) } else { // tidak ada messagebank dengan ann_id ini, delete from queue paging db.Delete_Queue_Paging_by_index(qp.index) @@ -333,30 +638,174 @@ fun main() { // prioritas 2, habisin queue table - db.Read_Queue_Table().forEach { - if (it.BroadcastZones.isNotEmpty()) { - val zz = it.BroadcastZones.split(";") + db.Read_Queue_Table().forEach { qa -> + if (qa.BroadcastZones.isNotEmpty()) { + val zz = qa.BroadcastZones.split(";") if (AllBroadcastZonesValid(zz)) { if (AllBroadcastZoneIdle(zz)) { - if (it.Type == "SOUNDBANK") { + if (qa.Type == "SOUNDBANK") { + val variables = Get_Soundbank_Data(qa.SB_TAGS) + val languages = qa.Language.split(";") + // cek apakah ANN_ID ada di SB_TAGS + val ann_id = variables?.get("ANN_ID")?.toIntOrNull() ?: 0 + if (ann_id==0){ + // not available from variables, try to get from Message column + val remark = variables?.get("REMARK").orEmpty() + when(remark){ + "GOP" -> { + //TODO Combobox First_Call_Message_Chooser + } + "GBD" ->{ + // TODO Combobox Second_Call_Message_Chooser + } + "GFC" ->{ + // TODO Combobox Final_Call_Message_Chooser + } + "FLD" ->{ + // TODO Combobox Landed_Message_Chooser + } + } + } - } else if (it.Type == "TIMER") { + // recheck again + if (ann_id == 0) { + db.Add_Log( + "AAS", + "Cancelled SOUNDBANK message with index ${qa.index} due to missing or invalid ANN_ID in SB_TAGS" + ) + db.Delete_Queue_Table_by_index(qa.index) + return@forEach + } + // sampe sini punya ann_id valid + val mblist = Get_MessageBank_by_id(ann_id, languages) + if (mblist.isNotEmpty()) { + mblist.forEach { mb -> + Get_Soundbank_Files(mb, variables ?: emptyMap(), { + listfile -> + val listafi = mutableListOf() + listfile.forEach { filenya -> + val afi = audioPlayer.LoadAudioFile(filenya) + if (afi.isValid()) { + listafi.add(afi) + } + } + val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Soundbank","")).toString() + audioPlayer.WavWriter(listafi, targetfile + ) { success, message -> + if (success) { + // file siap broadcast + val targetafi = audioPlayer.LoadAudioFile(targetfile) + if (targetafi.isValid()) { + zz.forEach { z1 -> + StreamerOutputs.values.find { it.channel == z1 } + ?.SendData( + targetafi.bytes, + { db.Add_Log("AAS", it) }, + { db.Add_Log("AAS", it) }) + } + val logmsg = + "Broadcast started SOUNDBANK message with generated file '$targetfile' to zones: ${qa.BroadcastZones}" + Logger.info { logmsg } + db.Add_Log("AAS", logmsg) + db.Delete_Queue_Table_by_index(qa.index) + } + } + db.Add_Log("AAS", message) + } + }, + { + err -> + db.Add_Log("AAS", err) + db.Delete_Queue_Table_by_index(qa.index) + }) + } + } else { + // tidak ada messagebank dengan ann_id ini, delete from queue table + db.Delete_Queue_Table_by_index(qa.index) + db.Add_Log( + "AAS", + "Cancelled SOUNDBANK message with index ${qa.index} due to ANN_ID $ann_id not found in Messagebank" + ) + } + } else if (qa.Type == "TIMER") { + val ann_id = Get_ANN_ID(qa.SB_TAGS) + if (ann_id > 0) { + val mblist = Get_MessageBank_by_id(ann_id, qa.Language.split(";")) + if (mblist.isNotEmpty()) { + mblist.forEach { + mb -> + Get_Soundbank_Files(mb, emptyMap(), { + listfile -> + val listafi = mutableListOf() + listfile.forEach { filenya -> + val afi = audioPlayer.LoadAudioFile(filenya) + if (afi.isValid()) { + listafi.add(afi) + } + } + val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Timer","")).toString() + audioPlayer.WavWriter(listafi, targetfile + ) { success, message -> + if (success) { + // file siap broadcast + val targetafi = audioPlayer.LoadAudioFile(targetfile) + if (targetafi.isValid()) { + zz.forEach { z1 -> + StreamerOutputs.values.find { it.channel == z1 } + ?.SendData( + targetafi.bytes, + { db.Add_Log("AAS", it) }, + { db.Add_Log("AAS", it) }) + } + val logmsg = + "Broadcast started TIMER message with generated file '$targetfile' to zones: ${qa.BroadcastZones}" + Logger.info { logmsg } + db.Add_Log("AAS", logmsg) + db.Delete_Queue_Table_by_index(qa.index) + } + } + db.Add_Log("AAS", message) + } + }, + { + err -> + db.Add_Log("AAS", err) + db.Delete_Queue_Table_by_index(qa.index) + }) + } + + } else { + // tidak ada messagebank dengan ann_id ini, delete from queue table + db.Delete_Queue_Table_by_index(qa.index) + db.Add_Log( + "AAS", + "Cancelled TIMER with index ${qa.index} due to ANN_ID $ann_id not found in Messagebank" + ) + } + } else { + // invalid ann_id, delete from queue table + db.Delete_Queue_Table_by_index(qa.index) + db.Add_Log( + "AAS", + "Cancelled TIMER with index ${qa.index} due to invalid ANN_ID" + ) + } } } } else { // ada broadcast zone yang tidak valid, delete from queue table - db.Delete_Queue_Table_by_index(it.index) + db.Delete_Queue_Table_by_index(qa.index) db.Add_Log( "AAS", - "Cancelled table message with index ${it.index} due to invalid broadcast zone" + "Cancelled table message with index ${qa.index} due to invalid broadcast zone" ) } } else { // invalid broadcast zone, delete from queue table - db.Delete_Queue_Table_by_index(it.index) - db.Add_Log("AAS", "Cancelled table message with index ${it.index} due to empty broadcast zone") + db.Delete_Queue_Table_by_index(qa.index) + db.Add_Log("AAS", "Cancelled table message with index ${qa.index} due to empty broadcast zone") } } diff --git a/src/codes/Somecodes.kt b/src/codes/Somecodes.kt index db6e0c0..27e3e05 100644 --- a/src/codes/Somecodes.kt +++ b/src/codes/Somecodes.kt @@ -12,6 +12,7 @@ import oshi.hardware.CentralProcessor import oshi.hardware.GlobalMemory import java.nio.file.Files import java.nio.file.Path +import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.util.function.Consumer import kotlin.io.path.name @@ -21,6 +22,8 @@ import kotlin.io.path.name class Somecodes { companion object { val current_directory : String = System.getProperty("user.dir") + val SoundbankResult_directory : Path = Path.of(current_directory,"SoundbankResult") + val PagingResult_directory : Path = Path.of(current_directory,"PagingResult") val si = SystemInfo() val processor: CentralProcessor = si.hardware.processor val memory : GlobalMemory = si.hardware.memory @@ -29,6 +32,7 @@ class Somecodes { val dateformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy") val timeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss") val timeformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm") + val filenameformat: DateTimeFormatter = DateTimeFormatter.ofPattern("ddMMyyyy_HHmmss") const val KB_threshold = 1024.0 const val MB_threshold = KB_threshold * 1024.0 const val GB_threshold = MB_threshold * 1024.0 @@ -354,6 +358,22 @@ class Somecodes { } return false } + + /** + * Generate a WAV file name with the current date and time. + * The file name format is: [prefix]_ddMMyyyy_HHmmss_[postfix].wav + * @param prefix An optional prefix to add before the date and time. + * @param postfix An optional postfix to add after the date and time. + * @return A string representing the generated WAV file name. + */ + fun Make_WAV_FileName(prefix: String, postfix: String) : String{ + val sb = StringBuilder() + if (prefix.isNotEmpty()){sb.append(prefix).append("_")} + sb.append(filenameformat.format(LocalDateTime.now())) + if (postfix.isNotEmpty()){sb.append("_").append(postfix)} + sb.append(".wav") + return sb.toString() + } }