-- Is alleen geschikt voor SAM Broadcaster v2017.8 en hoger!
-- En je moet een map aanmaken (d:\spraak)
Het klinkt zo!
Code: Selecteer alles
//============================================================
// TALKER SCRIPT - Automatische radio-omroeper
//
// Dit script doet het volgende:
// 1. Haalt het laatst gespeelde nummer op uit de geschiedenis
// 2. Haalt de volgende 3 nummers op uit de wachtrij
// 3. Bouwt een gesproken tekst op met tijd, terugblik en vooruitblik
// 4. Spreekt de tekst uit via Piper TTS (text-to-speech)
//============================================================
PAL.Loop := True ;
// Wacht 4 nummers voordat het start
PAL.WaitForPlayCount(4);
// --- VARIABELEN ---
// TDataSet is een soort tijdelijke tabel waarin queryresultaten worden opgeslagen
VAR SONGS_STRAKS, SONGS_GEWEEST : TDataSet;
// Tekststrings voor de opbouw van de omroeptekst
VAR Tekst, IntroTekst, Cmd, Uur, Minuut, AlbumJaar, station : string;
// Jaar wordt gebruikt om de leeftijd van een nummer te berekenen
// AantalStraks telt hoeveel nummers er in de wachtrij staan
VAR Jaar, AantalStraks : Integer;
// HeeftGeweest geeft aan of er een vorig nummer beschikbaar is in de geschiedenis
VAR HeeftGeweest : Boolean;
//Naam van station
station := 'Wout F M .' ;
// --- TEKSTARRAYS ---
// Dit zijn lijsten met variaties op dezelfde boodschap.
// RandomInt() kiest elke keer een willekeurig zinnetje uit de lijst,
// zodat de omroeper niet elke keer hetzelfde zegt.
// Let op: de arrays beginnen altijd bij index 0.
// Introductiezinnen voor het vorige nummer (16 variaties, index 0..15)
VAR SongIntro : array[0..15] of string = ['You just heard', 'That was', 'Playing moments ago', 'A true classic from', 'Recently on the air', 'Still sounding amazing:', 'One of the greatest tracks ever:', 'Straight from the music vault:', 'That legendary song was', 'Another timeless hit:', 'Just played for you:', 'Classic radio gold from', 'Bringing back memories:', 'That unforgettable song was', 'Music history right there:', 'An absolute favorite:' ];
// Tijdsaankondigingen (11 variaties, index 0..10)
VAR TimeLines : array[0..10] of string = ['It is now %time%', 'The clock says %time%', 'Right now it is %time%', 'Current local time: %time%', 'Almost impossible to believe, but it is already %time%', 'Time flies, it is %time%', 'You made it to %time%', 'Another great hour starts at %time%', 'Late night vibes at %time%', 'Early morning radio at %time%', 'The evening continues at %time%' ];
// Aankondigingen voor het volgende nummer (16 variaties, index 0..15)
VAR NextSong : array[0..15] of string = ['Coming up next', 'Up next on your radio', 'Stay tuned for', 'Coming your way next', 'Do not go anywhere', 'More music is on the way', 'Ready for another classic?', 'Next up', 'Here comes another favorite', 'The music continues with', 'Keep listening for', 'Another legendary song is next', 'We continue with', 'Your next song tonight', 'Back to the music with', 'Straight ahead' ];
// Stationsslogan aan het einde van de tekst (11 variaties, index 0..10)
VAR StationLines : array[0..10] of string = ['More music, less talk on %station%', 'The soundtrack of your day', 'Always the best classics on %station%', 'Playing the hits you love on %station%', 'Your music station', 'Where great music never stops on %station%', 'Broadcasting across the region', 'Keeping radio alive on %station%', 'Classic hits all day long on %station%', 'Music connects people on %station%', 'The home of great music. %station%' ];
// Trivia-zinnen over de leeftijd van een nummer (13 variaties, index 0..12)
// %years% is een tijdelijke aanduiding die later wordt vervangen door het echte getal
VAR TriviaLines : array[0..12] of string = ['That song is already %years% years old', 'Can you believe it? That track came out %years% years ago', 'Still popular after %years% years', 'A timeless classic for over %years% years', 'That hit has survived %years% years of music history', 'Some songs never age', 'Music like this never gets old', 'Still sounding fresh today', 'One of those songs everybody remembers', 'Turn it up, classics never disappoint', 'That track still fills dancefloors today', 'Pure nostalgia on the radio', 'A real anthem from another decade' ];
// --- DATABASE QUERIES ---
// Met QUERY() wordt informatie opgehaald uit de database van het radioprogramma.
// De SQL-opdracht bepaalt welke gegevens worden opgehaald.
// REPLACE(artist, "&", "and") zorgt dat een "&"-teken wordt omgezet naar "and",
// omdat TTS-engines het "&"-teken soms niet goed uitspreken.
// Haal de komende 3 nummers op uit de wachtrij (alleen nummers, songtype = "S")
SONGS_STRAKS := QUERY(
'SELECT REPLACE(artist, "&", "and") AS artist, title, albumyear, ' +
'count_played, count_requested, last_requested ' +
'FROM queuelist q JOIN songlist s ON q.songID = s.ID ' +
'WHERE songtype = "S" ORDER BY sortID LIMIT 3', [], True);
// Haal het meest recentelijk gespeelde nummer op uit de geschiedenis
SONGS_GEWEEST := QUERY(
'SELECT REPLACE(artist, "&", "and") AS artist, title, albumyear ' +
'FROM historylist WHERE songtype = "S" ORDER BY ID DESC LIMIT 1', [], True);
// --- TIJD OPHALEN ---
// FormatDateTime() zet de huidige systeemtijd om naar tekst
// 'hh' = uur met voorloopnul (bijv. 08), 'nn' = minuten met voorloopnul (bijv. 05)
Uur := FormatDateTime('hh', Now);
Minuut := FormatDateTime('nn', Now);
// --- TIJDSGROET BEPALEN ---
// Op basis van het uur wordt een passende begroeting gekozen
IF StrToInt(Uur) < 12 THEN
IntroTekst := 'Good morning! '
ELSE IF StrToInt(Uur) < 18 THEN
IntroTekst := 'Good afternoon! '
ELSE
IntroTekst := 'Good evening! ';
// Voeg een willekeurige tijdsaankondiging toe, gevolgd door het huidige tijdstip
// Voorbeeld: "Good morning! The clock says 08 45. "
IntroTekst := IntroTekst + StringReplace(TimeLines[RandomInt(11)], '%time%', Uur + ' ' + Minuut , TRUE) + '. ';
// --- VORIG NUMMER VERWERKEN ---
// Controleer of er überhaupt een nummer in de geschiedenis staat
// EOF betekent "End Of File" — als dit true is, is de dataset leeg
HeeftGeweest := NOT SONGS_GEWEEST.EOF;
IF HeeftGeweest THEN
BEGIN
// Bereken hoeveel jaar geleden het nummer is uitgebracht
// StrToInt() zet een tekst-getal om naar een echt getal zodat je ermee kunt rekenen
Jaar := StrToInt(FormatDateTime('yyyy', Now)) - StrToInt(SONGS_GEWEEST['albumyear']);
AlbumJaar := SONGS_GEWEEST['albumyear'];
// Voeg een willekeurige intro toe met titel en artiest van het vorige nummer
// Voorbeeld: "That was, Bohemian Rhapsody from Queen. "
IntroTekst := IntroTekst + SongIntro[RandomInt(16)] + ', '
+ SONGS_GEWEEST['title'] + ' from ' + SONGS_GEWEEST['artist'] + '. ';
// Voeg een trivia-opmerking toe over de leeftijd van het nummer
// Als het nummer minder dan 2 jaar oud is, wordt het als "nieuw" beschouwd
IF Jaar < 2 THEN
IntroTekst := IntroTekst
+ 'Also new music on this station. That track came out in ' + AlbumJaar + '. '
ELSE
// StringReplace() vervangt de tijdelijke aanduiding %years% door het echte aantal jaren
// Voorbeeld: "Still popular after 32 years. "
IntroTekst := IntroTekst
+ StringReplace(TriviaLines[RandomInt(13)], '%years%', IntToStr(Jaar), TRUE) + '. ';
END;
// --- VOLGENDE NUMMERS AANKONDIGEN ---
// Begin de aankondigingstekst met een willekeurige overgangsZin
// Voorbeeld: "Coming up next: "
Tekst := IntroTekst + NextSong[RandomInt(16)] + ': ';
// Loop door alle nummers in de wachtrij
// Na elk nummer (behalve het eerste) wordt een komma als scheidingsteken ingevoegd
AantalStraks := 0;
WHILE NOT SONGS_STRAKS.EOF DO
BEGIN
// Voeg een komma toe tussen nummers (niet vóór het eerste nummer)
IF AantalStraks > 0 THEN
Tekst := Tekst + ', ';
// Voeg titel en artiest toe
// Voorbeeld: "Bohemian Rhapsody from Queen"
Tekst := Tekst + SONGS_STRAKS['title'] + ' from ' + SONGS_STRAKS['artist'];
AantalStraks := AantalStraks + 1;
// Ga naar het volgende record in de dataset
SONGS_STRAKS.Next;
END;
// Sluit de nummerlijst af met een punt, of geef een fallback als de wachtrij leeg is
IF AantalStraks > 0 THEN
Tekst := Tekst + '. '
ELSE
Tekst := Tekst + 'great music. ';
// Voeg een willekeurige stationsslogan toe aan het einde
// Voorbeeld: "The soundtrack of your day."
//Tekst := Tekst + StationLines[RandomInt(11)] + '.';
Tekst := Tekst + StringReplace(StationLines[RandomInt(11)], '%station%', station, TRUE) + '. ';
// Schrijf de volledige tekst naar het logbestand
WriteLn(Tekst);
// --- TEXT-TO-SPEECH UITVOEREN ---
// De volledige tekst wordt via de commandoregel naar Piper gestuurd.
// Piper is een TTS-engine die de tekst omzet naar gesproken audio.
//
// Hoe de opdracht werkt:
// cd /d d:\spraak ? ga naar de map waar Piper staat
// echo [tekst] ? stuur de tekst naar de invoer van Piper
// piper.exe --model ... ? Piper zet de tekst om naar ruwe audiodata
// ffplay ... ? ffplay speelt de ruwe audiodata direct af
//
// Audioparameters voor ffplay:
// -f s16le ? audioformaat: 16-bit stereo little-endian
// -ar 22050 ? samplerate: 22050 Hz (standaard voor dit Piper-model)
// -autoexit ? ffplay sluit automatisch af als het afspelen klaar is
// -nodisp ? geen venster tonen tijdens afspelen
Cmd := '/C cd /d d:\spraak & echo ' + Tekst
+ ' | piper.exe --model en_US-ryan-high.onnx '
// Onderstaand voor test
//+ '--output_raw | ffplay -autoexit -nodisp -f s16le -ar 22050 -';
+ ' --output_file dj.wav' ;
ExecuteCmd('cmd.exe', [Cmd]);
//Plaats dj-bestand naar de bovenkant van de queue
Queue.Addfile('d:\spraak\dj.wav', IpTop) ;
