-- Harmonie is an virtual music composer.
-- Copyright (C) 2009 Manuel De Girardi
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------------
-- Author : Manuel De Girardi
-- Date : 2009/08/26
-- Version : 0.1.0-0a
-- Description : Compositeur-intepreteur de musique automatique.
-------------------------------------------------------------------------------
with Text_Io, Ada.Command_Line;
use Text_Io, Ada.Command_Line;
with Ada.Strings.Fixed;
use Ada.Strings.Fixed;
with Portmidi;
use Portmidi;
with Interfaces.C;
use Interfaces.C;
procedure Main is
subtype T_Channel is Natural range 0..15;
Default : constant String := "orchester.txt";
File : File_Type;
type T_Info is
record
Global_Channel : T_Channel;
Device_Id : Natural;
end record;
type T_Tab_Pos is array (Positive range 1..256) of T_info;
Tab_Pos : T_Tab_Pos;
line : String(1..64);
Last,
Choice : Natural := 0;
Char : Character;
Name : T_ErrorText;
device : Positive := 1;
Channel : Natural;
The_Deviceinfo : DeviceInfo;
use DeviceInfo_Conversion;
use ErrorText_Conversion;
begin
if Argument_count = 0 then
begin
Open(File, In_File, Default);
while not End_Of_File(File) loop
Get_Line(File, Line, Last);
Tab_Pos(Device).Device_Id := Natural'Value(Line(1..Index(Line, "," )-1));
Tab_Pos(Device).Global_Channel := Natural'Value(Line(Index(Line, "," )+1..last));
Device := Device+1;
end loop;
Close(File);
exception
when Name_Error =>
begin
Prepare0:
loop
Put_line("ID, Device Name" );
for I in 0..Pm_CountDevices-1 loop
The_DeviceInfo :=
DeviceInfo_Conversion.To_pointer
(Pm_GetDeviceInfo(I)).all;
if The_Deviceinfo.Output = 1 then
Name := To_Pointer(The_Deviceinfo.name).all;
Put(Integer'Image(I));
Put_line(", " & Interfaces.C.To_Ada(Name));
end if;
end loop;
loop
begin
Put("Enter output device ID of instrument" & Integer'Image(Device) & " or 'Enter' to terminate : " );
Get_line(line, Last);
if Last /= 0 then
Choice := Natural'Value(Line(1..Last));
else
exit Prepare0;
end if;
case Choice is
when 0..255 =>
Tab_Pos(Device).Device_Id := Choice;
exit;
when others =>
New_Line;
end case;
exception
when others =>
Last := 0;
Put("Press any key to continue" );
Skip_Line;
New_Line;
end;
end loop;
loop
begin
Put("Enter global channel for device ID " &
Integer'Image(Tab_Pos(Device).Device_Id) & ": " );
Get_line(line, Last);
if Last /= 0 then
Channel := Natural'Value(Line(1..Last));
else
Channel := 0;
end if;
case Channel is
when 0..15 =>
Tab_Pos(Device).Global_Channel := T_Channel(Channel);
Device := Device+1;
exit;
when others =>
New_Line;
end case;
exception
when others =>
Last := 0;
Put("Press any key to continue" );
Skip_Line;
New_Line;
end;
end loop;
end loop Prepare0;
if Device /= 0 then
loop
Put("Save configuration ? (y/n) : " );
Get_Immediate(Char);
case Char is
when 'Y' | 'y' =>
loop
begin
New_Line;
Put("Enter filename (Default=""orchester.txt"" ) : " );
Get_Line(Line, Last);
if Last /= 0 then
Create(File, Out_File, Line(1..Last));
else
Create(File, Out_File, Default);
end if;
for I in 1..Device-1 loop
Put_line(File, Integer'Image(Tab_Pos(I).Device_Id) &
',' &
Integer'Image(Tab_Pos(I).Global_Channel));
end loop;
Close(File);
exit;
exception
when Name_Error =>
Put_line("Filename is too long!" );
end;
end loop;
exit;
when 'N' | 'n' =>
exit;
when others =>
New_Line;
end case;
end loop;
end if;
end;
end;
else
begin
Open(File, In_File, Argument(1));
while not End_Of_File(File) loop
Get_Line(File, Line, Last);
Tab_Pos(Device).Device_Id := Natural'Value(Line(1..Index(Line, "," )-1));
Tab_Pos(Device).Global_channel := Natural'Value(Line(Index(Line, "," )+1..last));
Device := Device+1;
end loop;
Close(File);
exception
when Name_Error =>
begin
Prepare1:
loop
Put_line("ID, Device Name" );
for I in 0..Pm_CountDevices-1 loop
The_DeviceInfo :=
DeviceInfo_Conversion.To_pointer
(Pm_GetDeviceInfo(I)).all;
if The_Deviceinfo.Output = 1 then
Name := To_Pointer(The_Deviceinfo.name).all;
Put(Integer'Image(I));
Put_line(", " & Interfaces.C.To_Ada(Name));
end if;
end loop;
loop
begin
Put("Enter output device ID of instrument" & Integer'Image(Device) & " or 'Enter' to terminate : " );
Get_line(line, Last);
if Last /= 0 then
Choice := Natural'Value(Line(1..Last));
else
exit Prepare1;
end if;
case Choice is
when 0..255 =>
Tab_Pos(Device).Device_Id := Choice;
exit;
when others =>
New_Line;
end case;
exception
when others =>
Last := 0;
Put("Press any key to continue" );
Skip_Line;
New_Line;
end;
end loop;
loop
begin
Put("Enter global channel for device ID " &
Integer'Image(Tab_Pos(Device).Device_Id) & ": " );
Get_line(line, Last);
if Last /= 0 then
Channel := Natural'Value(Line(1..Last));
else
Channel := 0;
end if;
case Channel is
when 0..15 =>
Tab_Pos(Device).Global_Channel := T_Channel(Channel);
Device := Device+1;
exit;
when others =>
New_Line;
end case;
exception
when others =>
Last := 0;
Put("Press any key to continue" );
Skip_Line;
New_Line;
end;
end loop;
end loop Prepare1;
if Device /= 0 then
loop
Put("Save configuration ? (y/n) : " );
Get_Immediate(Char);
case Char is
when 'Y' | 'y' =>
loop
begin
New_Line;
Put("Enter filename (Default=""orchester.txt"" ) : " );
Get_Line(Line, Last);
if Last /= 0 then
Create(File, Out_File, Line(1..Last));
else
Create(File, Out_File, Default);
end if;
for I in 1..Device-1 loop
Put_line(File, Integer'Image(Tab_Pos(I).Device_Id) &
',' &
Integer'Image(Tab_Pos(I).Global_Channel));
end loop;
Close(File);
exit;
exception
when Name_Error =>
Put_line("Filename is too long!" );
end;
end loop;
exit;
when 'N' | 'n' =>
exit;
when others =>
New_Line;
end case;
end loop;
end if;
end;
end;
end if;
end Main;