• ANSI Music

    From xqtr@21:1/111 to All on Mon Feb 25 19:19:36 2019
    I was making some research on the subject and managed to make a small test program to play ansi music. Still the best solution is to use an old DOS app, in DOSBOX, but for anyone that wants to test it under linux here it is.
    Compile it with FreePascal and make sure you have SOX installed on your
    system. To install it: sudo apt-get install sox
    {
    __ _ __ _ _ __
    ______\ \_\\_______________________\///__________________________//_/ /______
    \___\ /___/
    | .__ __ |
    | | ___ __________/ |________ |
    | \ \/ / ____/\ __\_ __ \ |
    ; > < <_| | | | | | \/ ;
    : /__/\_ \__ | |__| |__| :
    . \/ |__| .
    . .
    . xqtr@gmx.com .

    : https://github.com/xqtr :: https://paypal.me/xqtr :
    ; ;
    + --- -- - . - --- --- --- - . - -- --- +

    This is a test program to play the old style, ansi music, with the help of
    SOX in linux machines. It doesn't work 100% but its too close, cause there
    are some undocumented areas in the ansi music format, like the < > chars.
    and the Txxx command. Whats the Tempo in ansi music, anyway?

    If someone knows more about, let me know. Also... i don't know shit about
    music, so the notes maybe different than the original.

    The idea is to translate the ANSI music notes, to a SOX frequency that can
    play. While playing the music, you will hear a noise from SOX when it
    starts and exits. I had the same idea to use SOX, as in this link:
    https://stackoverflow.com/questions/13760504/generate-tones-of-specific-
    frequency-on-mac-command-line
    Which i used to make the Playtone procedure, cause as i said... i ain't
    know shit about music.. :)

    }

    program ansimusic;

    uses
    crt,
    math,
    unix,
    sysutils;

    var
    f : text;
    b : byte;
    c : char;
    st : string;

    Octave : Byte = 4;
    ConstDuration : Real = 0.5;
    Duration : Real =0;
    LDur : Byte;

    Function Real2Str (R : Real; D:Byte) : String;
    Var S : String;
    begin
    Str (R:10:d,S);

    Real2Str:=S;
    end;

    procedure playtone(n:string; dur:real; oct:byte);
    const
    temp = 1.0594630943592952646;
    A4 = 440;
    var
    note_int:byte;
    A0 : Real;
    C0 : Real;
    HZ : Real;
    i:byte;
    begin
    for i:=1 to Length(n) Do
    n[i]:=Upcase(n[i]);
    case n of
    'A' : note_int:=10;
    'A#' : note_int:=11;
    'A-' : note_int:=9;
    'B' : note_int:=12;
    'B#' : note_int:=13;
    'B-' : note_int:=11;
    'C' : note_int:=0;
    'C#' : note_int:=1;
    'C-' : note_int:=13;
    'D' : note_int:=2;
    'D#' : note_int:=3;
    'D-' : note_int:=1;
    'E' : note_int:=4;
    'E#' : note_int:=5;
    'E-' : note_int:=3;
    'F' : note_int:=6;
    'F#' : note_int:=7;
    'F-' : note_int:=5;
    'G' : note_int:=8;
    'G#' : note_int:=9;
    'G-' : note_int:=7;
    end;
    A0 := A4 / 16;
    C0 := A0 * ( 1 / temp)**9;
    HZ := C0*Power(2,oct+1) * Power(temp,note_int);
    //HZ:=$( bc -l <<< "$C0_HZ * 2^$OCTAVE * $EQL_TEMPERAMENT ^ $NOTE_INT" )
    fpsystem('play -n synth '+Real2Str(dur,8)+' sin '+Real2Str(hz,8)+' 2>/dev/nul ');
    end;

    Procedure ProcessMusic(Music:string);
    Var
    snum:string;
    Count:Word;
    TCount:Word;
    Note:String;
    Begin
    Count:=1;
    While Count <= Length(Music) Do Begin

    if keypressed then begin
    halt;
    end;


    Write(Music[Count]);
    if (Music[Count]=#27) and (Music[Count+1]='F') Then Count:=Count+2;
    Case Music[Count] Of
    #27 : Count:=Count+1;
    '[' : Count:=Count+1;
    'L' : Begin
    TCount:=Count+1;
    SNum:='';
    While (Music[TCount] in ['0'..'9']) and (TCount<=Length(Music)) D
    Begin
    snum:=snum+Music[TCount];
    TCount:=TCount+1;
    End;
    If snum='' Then LDur:=1 Else Begin
    Count:=TCount;
    LDur := StrToInt(snum);
    Duration := ConstDuration / LDur;
    End;
    End;
    'T' : Begin
    TCount:=Count+1;
    SNum:='';
    While (Music[TCount] in ['0'..'9']) and (TCount<=Length(Music)) D
    Begin
    snum:=snum+Music[TCount];
    TCount:=TCount+1;
    End;
    If snum='' Then LDur:=1 Else Begin
    Count:=TCount;
    LDur := StrToInt(snum);
    Duration := ConstDuration / LDur;
    End;
    End;
    'O' : Begin
    Count:=Count+1;
    Octave:=StrToInt(Music[Count]);
    //Count:=Count+1;
    End;
    'M' : bEGIN
    Count:=Count+1;
    Case Music[Count+1] Of
    'L' : Begin
    LDur:=1;
    Duration := ConstDuration / LDur;
    End;
    'F' : ;
    'B' : ;
    'N' : Duration := (ConstDuration / LDur) * (7/8);
    'S' : Duration := (ConstDuration / LDur) * (3/4);
    End;

    Count:=Count+1;
    End;
    'P' : Begin
    TCount:=Count+1;
    SNum:='';
    While (Music[TCount] in ['0'..'9']) and (TCount<=Length(Music)) D
    Begin
    snum:=snum+Music[TCount];
    TCount:=TCount+1;
    End;
    Count:=TCount-1;
    Duration := ConstDuration / StrToInt(snum);
    Delay(Trunc(Duration));
    End;
    'N' : Begin
    Duration := (ConstDuration / LDur) * (7/8);
    COunt:=COunt+1;
    End;
    'S' : Begin
    Duration := (ConstDuration / LDur) * (3/4);
    COunt:=COunt+1;
    End;
    'A'..'G'
    : Begin
    Note:=Music[Count];
    If Count+1<=Length(Music) Then Begin
    if Music[Count+1] in ['#','+','-','.'] Then
    Case Music[Count+1] Of
    '+' : Begin
    Note:=Note+'#';
    COunt:=COunt+1;
    PlayTone(Note,Duration,Octave);
    End;
    '#' : Begin
    Note:=Note+'#';
    COunt:=COunt+1;
    PlayTone(Note,Duration,Octave);
    End;
    '-' : Begin
    Note:=Note+'-';
    COunt:=COunt+1;
    PlayTone(Note,Duration,Octave);
    End;
    '.' : Begin
    COunt:=COunt+1;
    PlayTone(Note,Duration+(Duration/2),Octave);
    End;
    End
    else PlayTone(Note,Duration+(Duration/2),Octave);

    End;
    COunt:=COunt+1;
    End;
    Else
    Count:=Count+1;
    End;



    End;
    End;

    procedure demo;
    begin
    ProcessMusic('MFT225O3L8GL8GL8GL2E-P8L8FL8FL8FML2DL2DP8');
    ProcessMusic('MFO3L8GL8GL8GL8E-L8A-L8A-L8A-L8GO4L8E-L8E-L8E-MLL2C');
    ProcessMusic('MFL8CMNO3L8GL8GL8GL8DL8A-L8A-L8A-L8GO4L8FL8FL8FMLL2DL2DMN');
    ProcessMusic('MFO4L8GL8GL8FL8E-O3L8E-L8E-L8FL8GO4L8GL8GL8FL8E-O3L8E-L8E-');
    ProcessMusic('MFL8FL8GO4L8GL8GL8FL8E-P4L8CP4L1GO3L8A-L8A-L8A-MLL2FL2FMN');
    ProcessMusic('MFP8O3L8A-L8A-L8A-L8FL8DL8DL8DO2L8BL8A-L8A-L8A-L8GO1L8GL8');
    ProcessMusic('MFGL8GL8CO3L8A-L8A-L8A-L8FL8DL8DL8DO2L8B-L8A-L8A-L8A-L8GO1');
    ProcessMusic('MFL8GL8GL8GL8CO3L8GO4L8CL8CL2CO3L8BL8BL8BO4L8DL2DL8DL8DL8D');
    ProcessMusic('MFL8E-L8E-L8DL8DL8FL8FL8EL8E-L8GT50O4L8GL8FL8FL8A-L8A-L8G');
    ProcessMusic('MFL8GL8B-L8B-L8A-L8A-L8CL8CL8BL8B-L8DL8CL8E-L8E-L8E-L8CL8');
    ProcessMusic('MFGL8GL8GL8E-L8CO3L8GL8GL8E-L8CL8CL8CO2L8B-O4L8FL8E-L8E-L8');
    ProcessMusic('MFBL8GL8FL8FL8DO3L8BL8GL8FL8DO2L8BO3L8CL8CL8CO4L8E-L8E-'); end;

    begin
    if (paramstr(1)='DEMO') or (paramstr(1)='demo') then begin
    demo;
    exit;
    end;
    if not fileexists(paramstr(1)) then begin
    writeln;
    writeln('File doesn''t exist. Aborting...');
    writeln('execute like this to hear a demo:');
    writeln('#> ./ansimus demo');
    writeln;
    exit;
    end;
    writeln('Get more songs here: http://artscene.textfiles.com/ansimusic/songs/' ;
    writeln('Press key to abort...');
    assign(f,paramstr(1));
    reset(f);
    While not eof(f) do begin
    readln(f,st);
    if st[1]=#27 then processmusic(st);
    writeln;
    end;
    close(f);
    end.

    .----- --- -- -
    | Another Droid BBS
    : Telnet : andr01d.zapto.org:9999 [UTC 11:00 - 20:00]
    . Contact : xqtr@gmx.com

    --- Mystic BBS v1.12 A41 2018/12/27 (Raspberry Pi/32)
    * Origin: Another Droid BBS # andr01d.zapto.org:9999 (21:1/111)