Friday, April 11, 2025

SAAN PROGRAMMING FOR RAGAS

upto try 18 midi ragas











https://drinkussions.blogspot.com/2025/04/saan-programming-for-ragas.html

1 0 NONE 8.18 0 0 1
2 1 NONE 8.66 3.114367025 3.032100843 1.027 1 0.083333333 1.064575137 8.70822462 8.666408112 8.666408112 0.006
3 2 NONE 9.18 3.198494154 3.114367025 1.027 2 0.166666667 1.069711846 9.263704585 9.181739555 9.181739555 0.002
4 3 NONE 9.72 3.280956314 3.198494154 1.026 3 0.25 1.07487334 9.86733726 9.727714201 0.008
5 4 NONE 10.3 3.364572432 3.280956314 1.025 4 0.333333333 1.080059739 10.49818066 10.30615419 0.006
6 5 NONE 10.91 3.447579197 3.364572432 1.025 5 0.416666667 1.085271163 11.17829298 10.91899001 0.009
7 6 NONE 11.56 3.531069493 3.447579197 1.024 6 0.5 1.090507733 11.89743936 11.56826694 0.008
8 7 NONE 12.25 3.614709844 3.531069493 1.024 7 0.583333333 1.09576957 12.66709622 12.25615189 0.006
9 8 NONE 12.98 3.698218478 3.614709844 1.023 8 0.666666667 1.101056795 13.48794574 12.98494061 0.005
10 9 NONE 13.75 3.781359714 3.698218478 1.022 9 0.75 1.106369533 14.36067654 13.75706535 0.007
11 10 NONE 14.57 3.864928972 3.781359714 1.022 10 0.833333333 1.111707905 15.28598369 14.57510303 0.005
12 11 NONE 15.43 3.947666157 3.864928972 1.021 11 0.916666667 1.117072035 16.27573955 15.44178376 0.012
13 12 NONE 16.35 4.031218731 3.947666157 1.021 0 0 1.059463094 16.34751555 16.34751555 -0.002
14 13 NONE 17.32 4.114367025 4.031218731 1.021 1 0.083333333 1.064575137 17.40580349 17.31958941 0
15 14 NONE 18.35 4.197708158 4.114367025 1.02 2 0.166666667 1.069711846 18.52740917 18.34946578 -0.001
16 15 NONE 19.45 4.28169825 4.197708158 1.02 3 0.25 1.07487334 19.72392579 19.4405818 -0.009
17 16 NONE 20.6 4.364572432 4.28169825 1.019 4 0.333333333 1.080059739 21.00716192 20.59657895 -0.003
18 17 NONE 21.83 4.448240225 4.364572432 1.019 5 0.416666667 1.085271163 22.35658596 21.82131527 -0.009
19 18 NONE 23.12 4.531069493 4.448240225 1.019 6 0.5 1.090507733 23.8057838 23.1188782 -0.001
20 19 NONE 24.5 4.614709844 4.531069493 1.018 7 0.583333333 1.09576957 25.33419245 24.49359823 -0.006
21 20 NONE 25.96 4.698218478 4.614709844 1.018 8 0.666666667 1.101056795 26.97589149 25.95006337 -0.01
22 21 A0 27.5 4.781359714 4.698218478 1.018 9 0.75 1.106369533 28.72135307 27.49313444 -0.007
23 22 A#0/Bb0 29.14 4.864928972 4.781359714 1.017 10 0.833333333 1.111707905 30.57196739 29.12796129 -0.012
24 23 B0 30.87 4.948133578 4.864928972 1.017 11 0.916666667 1.117072035 32.55147911 30.86 -0.01
25 24 C1 32.7 5.031218731 4.948133578 1.017 0 0 1.059463094 32.70562572 32.70562572 0.006
26 25 C#1/Db1 34.65 5.114783447 5.031218731 1.017 1 0.083333333 1.064575137 34.81160698 34.65040343 0
27 26 D1 36.71 5.198101209 5.114783447 1.016 2 0.166666667 1.069711846 37.06551546 36.71082364 0.001
28 27 D#1/Eb1 38.89 5.28132733 5.198101209 1.016 3 0.25 1.07487334 39.45860031 38.89376281 0.004
29 28 E1 41.2 5.364572432 5.28132733 1.016 4 0.333333333 1.080059739 42.00352325 41.2065063 0.007
30 29 F1 43.65 5.447909749 5.364572432 1.016 5 0.416666667 1.085271163 44.71317191 43.65677267 0.007
31 30 F#1/Gb1 46.25 5.531381461 5.447909749 1.015 6 0.5 1.090507733 47.60066253 46.25273946 0.003
32 31 G1 49 5.614709844 5.531381461 1.015 7 0.583333333 1.09576957 50.67934259 49.00307047 0.003
33 32 G#1/Ab1 51.91 5.697940583 5.614709844 1.015 8 0.666666667 1.101056795 53.95178298 51.91694468 0.007
34 33 A1 55 5.781359714 5.697940583 1.015 9 0.75 1.106369533 57.43164245 55.00408686 0.004
35 34 A#1/Bb1 58.27 5.864681406 5.781359714 1.014 10 0.833333333 1.111707905 61.14393477 58.27480006 0.005
36 35 B1 61.74 5.948133578 5.864681406 1.014 11 0.916666667 1.117072035 65.0917875 61.74 0
37 36 C2 65.41 6.031439309 5.948133578 1.014 0 0 1.059463094 65.41125145 65.41125145 0.001
38 37 C#2/Db2 69.3 6.114783447 6.031439309 1.014 1 0.083333333 1.064575137 69.63385971 69.30080686 0.001
39 38 D2 73.42 6.198101209 6.114783447 1.014 2 0.166666667 1.069711846 74.13103091 73.42164728 0.002
40 39 D#2/Eb2 77.78 6.28132733 6.198101209 1.013 3 0.25 1.07487334 78.91720062 77.78752562 0.008
41 40 E2 82.41 6.364747506 6.28132733 1.013 4 0.333333333 1.080059739 84.00704649 82.4130126 0.003
42 41 F2 87.31 6.448074996 6.364747506 1.013 5 0.416666667 1.085271163 89.43719653 87.31354534 0.004
43 42 F#2/Gb2 92.5 6.531381461 6.448074996 1.013 6 0.5 1.090507733 95.21223014 92.50547893 0.005
44 43 G2 98 6.614709844 6.531381461 1.013 7 0.583333333 1.09576957 101.3586852 98.00614095 0.006
45 44 G#2/Ab2 103.83 6.698079537 6.614709844 1.013 8 0.666666667 1.101056795 107.903566 103.8338894 0.004
46 45 A2 110 6.781359714 6.698079537 1.012 9 0.75 1.106369533 114.8743486 110.0081737 0.008
47 46 A#2/Bb2 116.54 6.864681406 6.781359714 1.012 10 0.833333333 1.111707905 122.2878695 116.5496001 0.01
48 47 B2 123.47 6.948016737 6.864681406 1.012 11 0.916666667 1.117072035 130.183575 123.48 0.01
49 48 C3 130.81 7.031329024 6.948016737 1.012 0 0 1.059463094 130.8119083 130.8119083 0.002
50 49 C#3/Db3 138.59 7.114679353 7.031329024 1.012 1 0.083333333 1.064575137 139.2570737 138.5903891 0
51 50 D3 146.83 7.198002957 7.114679353 1.012 2 0.166666667 1.069711846 148.2513647 146.8314025 0.001
52 51 D#3/Eb3 155.56 7.28132733 7.198002957 1.012 3 0.25 1.07487334 157.8236525 155.562452 0.002
53 52 E3 164.81 7.364659972 7.28132733 1.011 4 0.333333333 1.080059739 168.014093 164.8126768 0.003
54 53 F3 174.61 7.447992375 7.364659972 1.011 5 0.416666667 1.085271163 178.8635404 174.6129485 0.003
55 54 F#3/Gb3 185 7.531381461 7.447992375 1.011 6 0.5 1.090507733 190.4135552 184.9959748 -0.004
56 55 G3 196 7.614709844 7.531381461 1.011 7 0.583333333 1.09576957 202.7173704 195.9964079 -0.004
57 56 G#3/Ab3 207.65 7.698010062 7.614709844 1.011 8 0.666666667 1.101056795 215.8071319 207.6509608 0.001
58 57 A3 220 7.781359714 7.698010062 1.011 9 0.75 1.106369533 229.7376335 219.9985295 -0.001
59 58 A#3/Bb3 233.08 7.864681406 7.781359714 1.011 10 0.833333333 1.111707905 244.5757391 233.0803228 0
60 59 B3 246.94 7.948016737 7.864681406 1.011 11 0.916666667 1.117072035 260.36715 246.94 0
61 60 C4 (middle C) 261.63 8.031384168 7.948016737 1.01 0 0 1.059463094 261.6238165 261.6238165 -0.006
62 61 C#4/Db4 277.18 8.114679353 8.031384168 1.01 1 0.083333333 1.064575137 278.5247931 277.1807782 0.001
63 62 D4 293.66 8.198002957 8.114679353 1.01 2 0.166666667 1.069711846 296.5027294 293.662805 0.003
64 63 D#4/Eb4 311.13 8.2813737 8.198002957 1.01 3 0.25 1.07487334 315.647305 311.1249041 -0.005
65 64 E4 329.63 8.36470374 8.2813737 1.01 4 0.333333333 1.080059739 336.0389866 329.6253536 -0.005
66 65 F4 349.23 8.448033686 8.36470374 1.01 5 0.416666667 1.085271163 357.7379334 349.2258971 -0.004
67 66 F#4/Gb4 369.99 8.531342468 8.448033686 1.01 6 0.5 1.090507733 380.8380155 369.9919496 0.002
68 67 G4 392 8.614709844 8.531342468 1.01 7 0.583333333 1.09576957 405.423783 391.9928158 -0.007
69 68 G#4/Ab4 415.3 8.698010062 8.614709844 1.01 8 0.666666667 1.101056795 431.6142638 415.3019216 0.002
70 69 A4 concert pitch 440 8.781359714 8.698010062 1.01 9 0.75 1.106369533 459.475267 439.9970589 -0.003
71 70 A#4/Bb4 466.16 8.864681406 8.781359714 1.009 10 0.833333333 1.111707905 489.1514782 466.1606455 0.001
72 71 B4 493.88 8.948016737 8.864681406 1.009 11 0.916666667 1.117072035 520.7343 493.88 0
73 72 C5 523.25 9.031356596 8.948016737 1.009 0 0 1.059463094 523.247633 523.247633 -0.002
74 73 C#5/Db5 554.37 9.114705377 9.031356596 1.009 1 0.083333333 1.064575137 557.0389404 554.3615564 -0.008
75 74 D5 587.33 9.19802752 9.114705377 1.009 2 0.166666667 1.069711846 593.016156 587.32561 -0.004
76 75 D#5/Eb5 622.25 9.281350515 9.19802752 1.009 3 0.25 1.07487334 631.3053587 622.2498081 0
77 76 E5 659.26 9.36470374 9.281350515 1.009 4 0.333333333 1.080059739 672.0671725 659.2507072 -0.009
78 77 F5 698.46 9.448033686 9.36470374 1.009 5 0.416666667 1.085271163 715.4758668 698.4517942 -0.008
79 78 F#5/Gb5 739.99 9.531361965 9.448033686 1.009 6 0.5 1.090507733 761.676031 739.9838991 -0.006
80 79 G5 783.99 9.614691442 9.531361965 1.009 7 0.583333333 1.09576957 810.8585238 783.9856315 -0.004
81 80 G#5/Ab5 830.61 9.698027431 9.614691442 1.009 8 0.666666667 1.101056795 863.2175171 830.6038431 -0.006
82 81 A5 880 9.781359714 9.698027431 1.009 9 0.75 1.106369533 918.9615977 879.9941178 -0.006
83 82 A#5/Bb5 932.33 9.86469688 9.781359714 1.009 10 0.833333333 1.111707905 978.3029564 932.3212911 -0.009
84 83 B5 987.77 9.948031342 9.86469688 1.008 11 0.916666667 1.117072035 1041.479771 987.76 -0.01
85 84 C6 1046.5 10.0313566 9.948031342 1.008 0 0 1.059463094 1046.505861 1046.505861 0.006
86 85 C#6/Db6 1108.73 10.11469237 10.0313566 1.008 1 0.083333333 1.064575137 1114.077881 1108.734337 0.004
87 86 D6 1174.66 10.19802752 10.11469237 1.008 2 0.166666667 1.069711846 1186.021615 1174.663112 0.003
88 87 D#6/Eb6 1244.51 10.28136211 10.19802752 1.008 3 0.25 1.07487334 1262.610717 1244.512215 0.002
89 88 E6 1318.51 10.3646928 10.28136211 1.008 4 0.333333333 1.080059739 1344.145146 1318.514763 0.005
90 89 F6 1396.91 10.44802336 10.3646928 1.008 5 0.416666667 1.085271163 1430.940881 1396.917731 0.008
91 90 F#6/Gb6 1479.98 10.53136196 10.44802336 1.008 6 0.5 1.090507733 1523.341157 1479.982781 0.003
92 91 G6 1567.98 10.61469144 10.53136196 1.008 7 0.583333333 1.09576957 1621.717048 1567.987137 0.007
93 92 G#6/Ab6 1661.22 10.69802743 10.61469144 1.008 8 0.666666667 1.101056795 1726.435034 1661.224504 0.005
94 93 A6 1760 10.78135971 10.69802743 1.008 9 0.75 1.106369533 1837.923195 1760.006054 0.006
95 94 A#6/Bb6 1864.66 10.86469688 10.78135971 1.008 10 0.833333333 1.111707905 1956.605913 1864.66146 0.001
96 95 B6 1975.53 10.94802404 10.86469688 1.008 11 0.916666667 1.117072035 2082.959541 1975.54 0.01
97 96 C7 2093 11.0313566 10.94802404 1.008 0 0 1.059463094 2093.001127 2093.001127 0.001
98 97 C#7/Db7 2217.46 11.11469237 11.0313566 1.008 1 0.083333333 1.064575137 2228.155762 2217.45745 -0.003
99 98 D7 2349.32 11.19802752 11.11469237 1.007 2 0.166666667 1.069711846 2372.04323 2349.314332 -0.006
100 99 D#7/Eb7 2489.02 11.28136211 11.19802752 1.007 3 0.25 1.07487334 2525.221435 2489.011832 -0.008
101 100 E7 2637.02 11.3646928 11.28136211 1.007 4 0.333333333 1.080059739 2688.290291 2637.016177 -0.004
102 101 F7 2793.83 11.44802852 11.3646928 1.007 5 0.416666667 1.085271163 2861.881762 2793.821319 -0.009
103 102 F#7/Gb7 2959.96 11.53136196 11.44802852 1.007 6 0.5 1.090507733 3046.693219 2959.95058 -0.009
104 103 G7 3135.96 11.61469144 11.53136196 1.007 7 0.583333333 1.09576957 3243.434095 3135.9584 -0.002
105 104 G#7/Ab7 3322.44 11.69802743 11.61469144 1.007 8 0.666666667 1.101056795 3452.870068 3322.43219 -0.008
106 105 A7 3520 11.78135971 11.69802743 1.007 9 0.75 1.106369533 3675.846391 3519.994289 -0.006
107 106 A#7/Bb7 3729.31 11.86469301 11.78135971 1.007 10 0.833333333 1.111707905 3913.211825 3729.304042 -0.006
108 107 B7 3951.07 11.94802769 11.86469301 1.007 11 0.916666667 1.117072035 4165.907912 3951.06 -0.01
109 108 C8 4186.01 12.03136004 11.94802769 1.007 0 0 1.059463094 4186.012848 4186.012848 0.003
110 109 C#8/Db8 4434.92 12.11469237 12.03136004 1.007 1 0.083333333 1.064575137 4456.322169 4434.926125 0.006
111 110 D8 4698.64 12.19802752 12.11469237 1.007 2 0.166666667 1.069711846 4744.086459 4698.640556 0.001
112 111 D#8/Eb8 4978.03 12.28135921 12.19802752 1.007 3 0.25 1.07487334 5050.44287 4978.036263 0.006
113 112 E8 5274.04 12.3646928 12.28135921 1.007 4 0.333333333 1.080059739 5376.569782 5274.045703 0.006
114 113 F8 5587.65 12.44802594 12.3646928 1.007 5 0.416666667 1.085271163 5723.763524 5587.65678 0.007
115 114 F#8/Gb8 5919.91 12.53135953 12.44802594 1.007 6 0.5 1.090507733 6093.375532 5919.916142 0.006
116 115 G8 6271.93 12.61469374 12.53135953 1.007 7 0.583333333 1.09576957 6486.857232 6271.932674 0.003
117 116 G#8/Ab8 6644.88 12.69802743 12.61469374 1.007 8 0.666666667 1.101056795 6905.751147 6644.881199 0.001
118 117 A8 7040 12.78135971 12.69802743 1.007 9 0.75 1.106369533 7351.692782 7040.006397 0.006
119 118 A#8/Bb8 7458.62 12.86469301 12.78135971 1.007 10 0.833333333 1.111707905 7826.423651 7458.626961 0.007
120 119 B8 7902.13 12.94802587 12.86469301 1.006 11 0.916666667 1.117072035 8331.815824 7902.14 0.01
121 120 C9 8372.02 13.03136004 12.94802587 1.006 0 0 1.059463094 8372.015102 4186.012848 -4186.007
122 121 C#9/Db9 8869.84 13.11469237 13.03136004 1.006 1 0.083333333 1.064575137 8912.644338 4434.926125 -4434.914
123 122 D9 9397.27 13.19802599 13.11469237 1.006 2 0.166666667 1.069711846 9488.172918 4698.640556 -4698.629
124 123 D#9/Eb9 9956.06 13.28135921 13.19802599 1.006 3 0.25 1.07487334 10100.87499 4978.036263 -4978.024
125 124 E9 10548.08 13.3646928 13.28135921 1.006 4 0.333333333 1.080059739 10753.13956 5274.045703 -5274.034
126 125 F9 11175.3 13.44802594 13.3646928 1.006 5 0.416666667 1.085271163 11447.52705 5587.65678 -5587.643
127 126 F#9/Gb9 11839.82 13.53135953 13.44802594 1.006 6 0.5 1.090507733 12186.75106 5919.916142 -5919.904
128 127 G9 12543.85 13.61469259 13.53135953 1.006 7 0.583333333 1.09576957 12973.71446 6271.932674 -6271.917
129 128 G#9/Ab9 13289.75 13.69802635 13.61469259 1.006 8 0.666666667 1.101056795 13811.49128 6644.881199 -6644.869




namespace TRYING_GUITARS_BEHAGS
{
    public class BehagGuitarStrumming
    {
        static List<int> scaleNotes = new List<int>
        {
            60, 62, 64, 65, 67, 69, 71, 72, // Ascending
            71, 69, 67, 65, 64, 62, 60       // Descending
        };

        public static Dictionary<int, int> noteDurations = new Dictionary<int, int>
        {
            { 60, 500 }, { 62, 450 }, { 64, 400 },
            { 65, 500 }, { 67, 420 }, { 69, 400 },
            { 71, 430 }, { 72, 550 }
        };

        public static int Clamp(int value, int min, int max)
        {
            if (value < min) return min;
            if (value > max) return max;
            return value;
        }

        public static int GetVelocity(int note)
        {
            Random rand = new Random();
            return Clamp(105 - ((note - 60) * 2) + rand.Next(-8, 8), 70, 127);
        }

        public static void BehagGuitarStrumming___Main()
        {



            var midiEvents = new MidiEventCollection(1, 480);
            var rand = new Random();
            // int[] guitarPrograms = { 24, 25, 26, 27, 25, 26 }; // Nylon, Steel, Jazz, Clean
            int[] guitarPrograms = { 24, 25, 26, 27, 25, 26, 24, 23 }; // Nylon, Steel, Jazz, Clean

            for (int ch = 1; ch < (6 + 1); ch++)
            {
                try
                {
                    //  var track = new List<MidiEvent>();
                    //  midiEvents.AddTrack(track);
                    int tick = 0;
                    //  track.Add(new PatchChangeEvent(0, ch, guitarPrograms[ch]));

                    midiEvents.AddEvent(new PatchChangeEvent(0, ch, guitarPrograms[ch]), ch);

                    if (ch < 2)
                    {
                        // Strumming channel
                        for (int i = 0; i < 60; i++)
                        {
                            int baseNote = scaleNotes[rand.Next(scaleNotes.Count)];
                            int[] chord = { baseNote, baseNote + 4, baseNote + 7 }; // Major chord
                            int vel = GetVelocity(baseNote);
                            foreach (int n in chord)
                            {
                                //  track.Add(new NoteOnEvent(tick, ch, n, vel, 120));
                                //  track.Add(new NoteEvent(tick + 120, ch, MidiCommandCode.NoteOff, n, 0));

                                midiEvents.AddEvent(new NoteOnEvent(tick, ch, n, vel, 120), ch);
                            }//foreach (int n in chord)
                            tick += 240; // 1 beat strum
                        }//for (int i = 0; i < 60; i++)
                    }
                    // else if (ch < 5)
                    else if (ch < 6)
                    {
                        // Lead melody channel
                        for (int i = 0; i < scaleNotes.Count; i++)
                        {






















                            int note = scaleNotes[i];
                            int vel = GetVelocity(note);
                            int duration = noteDurations[note] + rand.Next(-20, 50);
                            int ticks = (int)(duration / 2.5);
                            //////track.Add(new ControlChangeEvent(tick, ch, MidiController.Modulation, rand.Next(40, 90)));
                            //////track.Add(new PitchWheelChangeEvent(tick, ch, rand.Next(3000, 9000)));
                            //////track.Add(new NoteOnEvent(tick, ch, note, vel, ticks));
                            //////track.Add(new NoteEvent(tick + ticks, ch, MidiCommandCode.NoteOff, note, 0));





                            midiEvents.AddEvent(new ControlChangeEvent(tick, ch, MidiController.Modulation, rand.Next(40, 90)), ch);
                            midiEvents.AddEvent(new PitchWheelChangeEvent(tick, ch, rand.Next(3000, 9000)), ch);
                            midiEvents.AddEvent(new NoteOnEvent(tick, ch, note, vel, ticks), ch);
                            midiEvents.AddEvent(new NoteEvent(tick + ticks, ch, MidiCommandCode.NoteOff, note, 0), ch);
                            //for ref  midiEvents.AddEvent(new NoteOnEvent(tick, ch, n, vel, 120), ch);


                            tick += ticks + rand.Next(20, 80);
                        }//for (int i = 0; i < scaleNotes.Count; i++)
                    }
                    else
                    {
                        // Bass channel or rhythm filler
                        for (int i = 1; i < (40 + 1); i++)
                        {
                            int note = scaleNotes[rand.Next(3)]; // lower notes only
                            int vel = GetVelocity(note) - 10;
                            int ticks = 160;
                            //  track.Add(new NoteOnEvent(tick, ch, note - 12, vel, ticks));
                            //  track.Add(new NoteEvent(tick + ticks, ch, MidiCommandCode.NoteOff, note - 12, 0));



                            midiEvents.AddEvent(new NoteOnEvent(tick, ch, note - 12, vel, ticks), ch);
                            //for refs midiEvents.AddEvent(new NoteOnEvent(tick, ch, n, vel, 120), ch);

                            tick += 320;
                        }//for (int i = 1; i < (40+1); i++)
                    }//end of else
                    //track.Add(new MetaEvent(MetaEventType.EndTrack, 0, tick + 200));

                }
                catch (Exception _excp)
                {
                    System.Windows.Forms.MessageBox.Show("_excp = " + _excp.Message + "   " + _excp.StackTrace.ToString() + " ch = " + ch);

                }//catch(Exception _excp)
            }//for (int ch = 1; ch < (6 + 1); ch++)

            string fileName = Path.Combine("d:\\Behag_Guitar_Strumming.mid");
            midiEvents.PrepareForExport(); // this is necessary
            MidiFile.Export(fileName, midiEvents);
            Console.WriteLine("Behag Guitar MIDI with Strumming saved to: " + fileName);
            System.Windows.Forms.MessageBox.Show("Behag Guitar MIDI with Strumming saved to: " + fileName);




        }




    }//public class BehagGuitarStrumming
}//namespace TRYING_GUITARS_BEHAGS




      private void button_TRYRAGAS_Click(object sender, EventArgs e)
        {
            /// THERE IS MISSING ENDTRACK
            //////   var midiEventCollection = new MidiEventCollection(1, 480);
            //////   int flutePatch = 73;  // Flute
            //////   int tablaChannel = 9; // Percussion
            //////   int tablaNote1 = 60;  // Dha
            //////   int tablaNote2 = 63;  // Tin
            //////   // Assign Flute to channels 0–5
            //////   for (int ch = 1; ch < (6+1); ch++)
            //////   {
            //////       midiEventCollection.AddEvent(new PatchChangeEvent(0, ch, flutePatch), 0);
            //////   }
            //////   // Define Behag notes (MIDI numbers)
            //////   int[] notes = { 60, 64, 65, 67, 69, 67, 65, 64, 62, 60 };
            //////   int[] durations = { 480, 240, 240, 480, 480, 240, 240, 480, 240, 480 };
            //////   int absoluteTime = 0;
            //////   // Add flute on multiple channels with effects
            //////   for (int i = 0; i < notes.Length; i++)
            //////   {
            //////       for (int ch = 1; ch < (6+1); ch++)
            //////       {
            //////           int delay = ch * 10; // slight strum delay
            //////           int time = absoluteTime + delay;
            //////           midiEventCollection.AddEvent(new NoteOnEvent(time, ch, notes[i], 80, durations[i]), 0);
            //////           midiEventCollection.AddEvent(new ChannelAfterTouchEvent(time + durations[i] / 3, ch, 60), 0);
            //////           midiEventCollection.AddEvent(new PitchWheelChangeEvent(time + (2 * durations[i]) / 3, ch, 8192 + 300), 0);
            //////           midiEventCollection.AddEvent(new NoteEvent(time + durations[i], ch, MidiCommandCode.NoteOff, notes[i], 64), 0);
            //////       }
            //////       absoluteTime += durations[i];
            //////   }
            //////   // Add tabla (loop pattern)
            //////   int tablaTime = 0;
            //////   while (tablaTime < 3 * 60 * 480) // approx 3 minutes
            //////   {
            //////       midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote1, 100, 240), 1);
            //////       tablaTime += 240;
            //////       midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote2, 100, 240), 1);
            //////       tablaTime += 240;
            //////       midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote2, 100, 240), 1);
            //////       tablaTime += 240;
            //////       midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote1, 100, 240), 1);
            //////       tablaTime += 240;
            //////   }
            //////   // Save MIDI
            //////   var midiFile = new MidiFile(1, (short)midiEventCollection.DeltaTicksPerQuarterNote);
            //////   //////SAANAUDS.Midi.MidiFile.Export
            //////   //////    (
            //////   //////    fileName_for_midi_from_the_dxf
            //////   //////    , collection
            //////   //////    );
            //////   SAANAUDS.Midi.MidiFile.Export("d:\\BehagWithTablaAndFlute.mid", midiEventCollection);
            ////////   MidiFile.Export("d:\\BehagWithTablaAndFlute.mid", midiEventCollection);
            var midiEventCollection = new MidiEventCollection(1, 480);
            int flutePatch = 73;  // Flute
            int tablaChannel = 9; // Percussion
            int tablaNote1 = 60;  // Dha
            int tablaNote2 = 63;  // Tin
                                  // Assign Flute to channels 0–5
            for (int ch = 1; ch < 6 + 1; ch++)
            {
                midiEventCollection.AddEvent(new PatchChangeEvent(0, ch, flutePatch), ch);
            }
            // Define Behag notes (MIDI numbers)
            int[] notes = { 60, 64, 65, 67, 69, 67, 65, 64, 62, 60 };
            int[] durations = { 480, 240, 240, 480, 480, 240, 240, 480, 240, 480 };
            int absoluteTime = 0;
            // Add flute on multiple channels with effects
            for (int i = 0; i < notes.Length; i++)
            {
                for (int ch = 1; ch < 6 + 1; ch++)
                {
                    int delay = ch * 10; // slight strum delay
                    int time = absoluteTime + delay;
                    midiEventCollection.AddEvent(new NoteOnEvent(time, ch, notes[i], 80, durations[i]), ch);
                    midiEventCollection.AddEvent(new ChannelAfterTouchEvent(time + durations[i] / 3, ch, 60), ch);
                    midiEventCollection.AddEvent(new PitchWheelChangeEvent(time + (2 * durations[i]) / 3, ch, 8192 + 300), ch);
                    midiEventCollection.AddEvent(new NoteEvent(time + durations[i], ch, MidiCommandCode.NoteOff, notes[i], 64), ch);
                }//for (int ch = 1; ch < 6 + 1; ch++)
                absoluteTime += durations[i];
            }//for (int i = 0; i < notes.Length; i++)
            // Add tabla (loop pattern)
            int tablaTime = 0;
            int  tabla___cycles___count = 0;
            int tabla___beats___count = 0;
            long tabla_cycle_restart_time_long = 0;
            while (tablaTime < 3 * 60 * 480) // approx 3 minutes
            {
                midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote1, 100, 240), tablaChannel);
                tablaTime += 240;
                tabla___beats___count ++;
                midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote2, 100, 240), tablaChannel);
                tablaTime += 240;
                tabla___beats___count ++;
                midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote2, 100, 240), tablaChannel);
                tablaTime += 240;
                tabla___beats___count ++;
                midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote1, 100, 240), tablaChannel);
                tablaTime += 240;
                tabla___beats___count++;
                tabla___cycles___count ++;
                tabla_cycle_restart_time_long += 240 * 4;
                //////saan adds this repeats
                ///
                // Add flute on multiple channels with effects
                for (int i = 0; i < notes.Length; i++)
                {
                    for (int ch = 1; ch < 6 + 1; ch++)
                    {
                        int delay = ch * 10; // slight strum delay
                        long repeat_time = tabla_cycle_restart_time_long + absoluteTime + delay;
                        midiEventCollection.AddEvent(new NoteOnEvent(repeat_time, ch, notes[i], 80, durations[i]), ch);
                        midiEventCollection.AddEvent(new ChannelAfterTouchEvent(repeat_time + durations[i] / 3, ch, 60), ch);
                        midiEventCollection.AddEvent(new PitchWheelChangeEvent(repeat_time + (2 * durations[i]) / 3, ch, 8192 + 300), ch);
                        midiEventCollection.AddEvent(new NoteEvent(repeat_time + durations[i], ch, MidiCommandCode.NoteOff, notes[i], 64), ch);
                    }//for (int ch = 1; ch < 6 + 1; ch++)
                    absoluteTime += durations[i];
                }//for (int i = 0; i < notes.Length; i++)
            }// while (tablaTime < 3 * 60 * 480) // approx 3 minutes
            // Add EndTrack event for each track
            //  midiEventCollection.AddEvent(new MetaEvent(MetaEventType.EndTrack, 0, 0), 0);
            // midiEventCollection.AddEvent(new MetaEvent(MetaEventType.EndTrack, 0, 0), 1);
            // Save MIDI
            midiEventCollection.PrepareForExport();//this is necessary
            var midiFile = new MidiFile(1, (short)midiEventCollection.DeltaTicksPerQuarterNote);
            SAANAUDS.Midi.MidiFile.Export("d:\\BehagWithTablaAndFlute.mid", midiEventCollection);
            System.Windows.Forms.MessageBox.Show("Files saved at d:\\BehagWithTablaAndFlute.mid");
        }//private void button_TRYRAGAS_Click(object sender, EventArgs e)



ALL DATA IN STRINGS  ROW NUMBER , NOTE_NUMBER_STARTING_FROM_1 , NOTES NAMES , FREQUENCY IN HERTZ
0,,,
1,0,NONE,8.18
2,1,NONE,8.66
3,2,NONE,9.18
4,3,NONE,9.72
5,4,NONE,10.3
6,5,NONE,10.91
7,6,NONE,11.56
8,7,NONE,12.25
9,8,NONE,12.98
10,9,NONE,13.75
11,10,NONE,14.57
12,11,NONE,15.43
13,12,NONE,16.35
14,13,NONE,17.32
15,14,NONE,18.35
16,15,NONE,19.45
17,16,NONE,20.6
18,17,NONE,21.83
19,18,NONE,23.12
20,19,NONE,24.5
21,20,NONE,25.96
22,21,A0,27.5
23,22,A#0/Bb0,29.14
24,23,B0,30.87
25,24,C1,32.7
26,25,C#1/Db1,34.65
27,26,D1,36.71
28,27,D#1/Eb1,38.89
29,28,E1,41.2
30,29,F1,43.65
31,30,F#1/Gb1,46.25
32,31,G1,49
33,32,G#1/Ab1,51.91
34,33,A1,55
35,34,A#1/Bb1,58.27
36,35,B1,61.74
37,36,C2,65.41
38,37,C#2/Db2,69.3
39,38,D2,73.42
40,39,D#2/Eb2,77.78
41,40,E2,82.41
42,41,F2,87.31
43,42,F#2/Gb2,92.5
44,43,G2,98
45,44,G#2/Ab2,103.83
46,45,A2,110
47,46,A#2/Bb2,116.54
48,47,B2,123.47
49,48,C3,130.81
50,49,C#3/Db3,138.59
51,50,D3,146.83
52,51,D#3/Eb3,155.56
53,52,E3,164.81
54,53,F3,174.61
55,54,F#3/Gb3,185
56,55,G3,196
57,56,G#3/Ab3,207.65
58,57,A3,220
59,58,A#3/Bb3,233.08
60,59,B3,246.94
61,60,C4 (middle C),261.63
62,61,C#4/Db4,277.18
63,62,D4,293.66
64,63,D#4/Eb4,311.13
65,64,E4,329.63
66,65,F4,349.23
67,66,F#4/Gb4,369.99
68,67,G4,392
69,68,G#4/Ab4,415.3
70,69,A4 concert pitch,440
71,70,A#4/Bb4,466.16
72,71,B4,493.88
73,72,C5,523.25
74,73,C#5/Db5,554.37
75,74,D5,587.33
76,75,D#5/Eb5,622.25
77,76,E5,659.26
78,77,F5,698.46
79,78,F#5/Gb5,739.99
80,79,G5,783.99
81,80,G#5/Ab5,830.61
82,81,A5,880
83,82,A#5/Bb5,932.33
84,83,B5,987.77
85,84,C6,1046.5
86,85,C#6/Db6,1108.73
87,86,D6,1174.66
88,87,D#6/Eb6,1244.51
89,88,E6,1318.51
90,89,F6,1396.91
91,90,F#6/Gb6,1479.98
92,91,G6,1567.98
93,92,G#6/Ab6,1661.22
94,93,A6,1760
95,94,A#6/Bb6,1864.66
96,95,B6,1975.53
97,96,C7,2093
98,97,C#7/Db7,2217.46
99,98,D7,2349.32
100,99,D#7/Eb7,2489.02
101,100,E7,2637.02
102,101,F7,2793.83
103,102,F#7/Gb7,2959.96
104,103,G7,3135.96
105,104,G#7/Ab7,3322.44
106,105,A7,3520
107,106,A#7/Bb7,3729.31
108,107,B7,3951.07
109,108,C8,4186.01
110,109,C#8/Db8,4434.92
111,110,D8,4698.64
112,111,D#8/Eb8,4978.03
113,112,E8,5274.04
114,113,F8,5587.65
115,114,F#8/Gb8,5919.91
116,115,G8,6271.93
117,116,G#8/Ab8,6644.88
118,117,A8,7040
119,118,A#8/Bb8,7458.62
120,119,B8,7902.13
121,120,C9,8372.02
122,121,C#9/Db9,8869.84
123,122,D9,9397.27
124,123,D#9/Eb9,9956.06
125,124,E9,10548.08
126,125,F9,11175.3
127,126,F#9/Gb9,11839.82
128,127,G9,12543.85
129,128,G#9/Ab9,13289.75
_______________________________________


ALL DATA IN STRINGS  ROW NUMBER , PATCH_INSTRUMENTS_NUMBER ,MIDI_PATCH_INSTRUMENTS_NAMES
0,,
1,1,Acoustic Grand Piano
2,2,Bright Acoustic Piano
3,3,Electric Grand Piano
4,4,Honky-tonk Piano
5,5,Electric Piano 1 (Rhodes Piano)
6,6,Electric Piano 2 (Chorused Piano)
7,7,Harpsichord
8,8,Clavinet
9,9,Celesta
10,10,Glockenspiel
11,11,Music Box
12,12,Vibraphone
13,13,Marimba
14,14,Xylophone
15,15,Tubular Bells
16,16,Dulcimer (Santur)
17,17,Drawbar Organ (Hammond)
18,18,Percussive Organ
19,19,Rock Organ
20,20,Church Organ
21,21,Reed Organ
22,22,Accordion (French)
23,23,Harmonica
24,24,Tango Accordion (Band neon)
25,25,Acoustic Guitar (nylon)
26,26,Acoustic Guitar (steel)
27,27,Electric Guitar (jazz)
28,28,Electric Guitar (clean)
29,29,Electric Guitar (muted)
30,30,Overdriven Guitar
31,31,Distortion Guitar
32,32,Guitar harmonics
33,33,Acoustic Bass
34,34,Electric Bass (fingered)
35,35,Electric Bass (picked)
36,36,Fretless Bass
37,37,Slap Bass 1
38,38,Slap Bass 2
39,39,Synth Bass 1
40,40,Synth Bass 2
41,41,Violin
42,42,Viola
43,43,Cello
44,44,Contrabass
45,45,Tremolo Strings
46,46,Pizzicato Strings
47,47,Orchestral Harp
48,48,Timpani
49,49,String Ensemble 1 (strings)
50,50,String Ensemble 2 (slow strings)
51,51,SynthStrings 1
52,52,SynthStrings 2
53,53,Choir Aahs
54,54,Voice Oohs
55,55,Synth Voice
56,56,Orchestra Hit
57,57,Trumpet
58,58,Trombone
59,59,Tuba
60,60,Muted Trumpet
61,61,French Horn
62,62,Brass Section
63,63,SynthBrass 1
64,64,SynthBrass 2
65,65,Soprano Sax
66,66,Alto Sax
67,67,Tenor Sax
68,68,Baritone Sax
69,69,Oboe
70,70,English Horn
71,71,Bassoon
72,72,Clarinet
73,73,Piccolo
74,74,Flute
75,75,Recorder
76,76,Pan Flute
77,77,Blown Bottle
78,78,Shakuhachi
79,79,Whistle
80,80,Ocarina
81,81,Lead 1 (square wave)
82,82,Lead 2 (sawtooth wave)
83,83,Lead 3 (calliope)
84,84,Lead 4 (chiffer)
85,85,Lead 5 (charang)
86,86,Lead 6 (voice solo)
87,87,Lead 7 (fifths)
88,88,Lead 8 (bass + lead)
89,89,Pad 1 (new age Fantasia)
90,90,Pad 2 (warm)
91,91,Pad 3 (polysynth)
92,92,Pad 4 (choir space voice)
93,93,Pad 5 (bowed glass)
94,94,Pad 6 (metallic pro)
95,95,Pad 7 (halo)
96,96,Pad 8 (sweep)
97,97,FX 1 (rain)
98,98,FX 2 (soundtrack)
99,99,FX 3 (crystal)
100,100,FX 4 (atmosphere)
101,101,FX 5 (brightness)
102,102,FX 6 (goblins)
103,103,FX 7 (echoes, drops)
104,104,FX 8 (sci-fi, star theme)
105,105,Sitar
106,106,Banjo
107,107,Shamisen
108,108,Koto
109,109,Kalimba
110,110,Bag pipe
111,111,Fiddle
112,112,Shanai
113,113,Tinkle Bell
114,114,Agogo
115,115,Steel Drums
116,116,Woodblock
117,117,Taiko Drum
118,118,Melodic Tom
119,119,Synth Drum
120,120,Reverse Cymbal
121,121,Guitar Fret Noise
122,122,Breath Noise
123,123,Seashore
124,124,Bird Tweet
125,125,Telephone Ring
126,126,Helicopter
127,127,Applause
128,128,Gunshot








Try 1

  নিচের C# কোডটা NAudio দিয়ে চালালে এবং Behag রাগ + তবলা সহ MIDI ফাইল বানাতে হলে 
আধুনিক পদ্ধতি তে গাণিতিক ভাবে ও NAudio C# Code (Behag + Tabla with Strumming and natural Effects) তৈরি করে দেখতে শুনতে হলে 

using NAudio.Midi;

class BehagWithTabla
{
    static void Main()
    {
        var midiEventCollection = new MidiEventCollection(1, 480);

        int flutePatch = 73;  // Flute
        int tablaChannel = 9; // Percussion
        int tablaNote1 = 60;  // Dha
        int tablaNote2 = 63;  // Tin

        // Assign Flute to channels 0–5
        for (int ch = 0; ch < 6; ch++)
        {
            midiEventCollection.AddEvent(new PatchChangeEvent(0, ch, flutePatch), 0);
        }

        // Define Behag notes (MIDI numbers)
        int[] notes = { 60, 64, 65, 67, 69, 67, 65, 64, 62, 60 };
        int[] durations = { 480, 240, 240, 480, 480, 240, 240, 480, 240, 480 };

        int absoluteTime = 0;

        // Add flute on multiple channels with effects
        for (int i = 0; i < notes.Length; i++)
        {
            for (int ch = 0; ch < 6; ch++)
            {
                int delay = ch * 10; // slight strum delay
                int time = absoluteTime + delay;
                midiEventCollection.AddEvent(new NoteOnEvent(time, ch, notes[i], 80, durations[i]), 0);
                midiEventCollection.AddEvent(new ChannelAfterTouchEvent(time + durations[i] / 3, ch, 60), 0);
                midiEventCollection.AddEvent(new PitchWheelChangeEvent(time + (2 * durations[i]) / 3, ch, 8192 + 300), 0);
                midiEventCollection.AddEvent(new NoteEvent(time + durations[i], ch, MidiCommandCode.NoteOff, notes[i], 64), 0);
            }

            absoluteTime += durations[i];
        }

        // Add tabla (loop pattern)
        int tablaTime = 0;
        while (tablaTime < 3 * 60 * 480) // approx 3 minutes
        {
            midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote1, 100, 240), 1);
            tablaTime += 240;
            midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote2, 100, 240), 1);
            tablaTime += 240;
            midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote2, 100, 240), 1);
            tablaTime += 240;
            midiEventCollection.AddEvent(new NoteOnEvent(tablaTime, tablaChannel, tablaNote1, 100, 240), 1);
            tablaTime += 240;
        }

        // Save MIDI
        var midiFile = new MidiFile(1, midiEventCollection.DeltaTicksPerQuarterNote);
        MidiFile.Export("BehagWithTablaAndFlute.mid", midiEventCollection);
    }
}
এখানে কিছু প্রয়োজনীয় প্রোগ্রামিং এর প্রশ্নগুলোর উত্তর একত্রিত করা হচ্ছে 
Channel Pressure যতবার খুশি apply করা যায়, note on এর পর যে কোনো সময় add করা যায়।
Pitch Bend প্রতি চ্যানেলে প্রতিটি টিকেও করা যায়। কিন্তু flute ও সেইক্ষেত্রে ড্রাম বিট এর মতন লাগবে।
Breathe Control Channel Pressure দিয়েই simulate করা যায়, frequency high হলেই বেশি চাপ।
Minimum Duration: Flute এ realistic শুনতে হলে 200ms বা তার বেশি রাখতে হয় সাধারণত। একসাথে অনেক নোট হলে 100ms রাখা যায়।

__________________

Try 2

তবলার ক্ষেত্রে General MIDI (GM) সিস্টেমে Drum sounds এর জন্য আলাদা কোনো "patch number" (Program Change) দিতে হয় না। কারণ

Drum / Percussion চ্যানেল (Channel 10 বা index 9):

Channel 10 (MIDI channel index 9) হচ্ছে GM Standard Drum Channel।

এই চ্যানেলে instrument patch change প্রযোজ্য না — কারণ প্রতিটি note number নিজে নিজেই একটি specific percussion sound বোঝায়।
তবলা related drum sounds

তবলা GM drum bank এ সরাসরি নেই, তবে নিম্নোক্ত note numbers ব্যবহারে তবলার কাছাকাছি ইফেক্ট পাওয়া যায়
 অনেক sound module বা VST plugin (যেমন: Indian Percussion VSTs) তবলার জন্য আলাদা patch বা kit রাখে, কিন্তু standard MIDI file এর মধ্যে এসব ড্রাম চ্যানেলেই বেজে থাকে।

NAudio-তে কোনো patch দরকার নেই এই জন্যে

// Channel 9 is drum channel, no patch change needed
midiEvents.AddEvent(new NoteOnEvent(tick, 9, 60, 90, 120), 1); // Dha

তবলা বাজাতে চাইলে Channel 9 (i.e., MIDI channel 10) ব্যবহার করো।

Program Change ইভেন্ট একেবারেই দরকার নেই ড্রাম চ্যানেলে।কোনো Indian VST instrument ব্যবহার করে তবলা সাউন্ড আরও রিচ করতে পারি কিন্তু সেটা MIDI standard এর বাইরে।

_____________

Try 3

 এখন আমরা Behag রাগের জন্য যে MIDI ফাইল তৈরি করছিলাম, তাতে একটি প্রোফেশনাল তবলা লুপ যোগ করব, যাতে পুরো কম্পোজিশন আরও প্রাণবন্ত ও ভারতীয় শাস্ত্রীয় সংগীতধর্মী হয়ে ওঠে।
মিডি প্রোগ্রামিং এ তবলা Loop সংযুক্ত করা 
 Overview
আমরা 1টি নতুন চ্যানেল (Channel 9 অর্থাৎ Standard Drum Channel in GM MIDI) ব্যবহার করব।

আমরা একটি সাধারণ Teentaal (16-beat) বা Keharwa (8-beat) এর প্যাটার্ন ব্যবহার করব Behag-এর mood অনুযায়ী।

GM MIDI তে তবলার জন্য কিছু percussive sound ব্যবহৃত হবে, যেমন

Tabla Dayan → MIDI note 60

Tabla Bayan → MIDI note 59

Muted Slap / Na / Tin / Tun → MIDI notes 61-67 (approx)
Behag + Guitar + Tabla (NAudio C# code snippet)
 আগের Behag কোডে শুধু নিচের অংশটা যোগ করবো এবার 

// Channel 9 (Drums) Tabla Loop - Teentaal/Keharwa style
var tablaTrack = new List<MidiEvent>();
midiEvents.AddTrack(tablaTrack);

int tablaTick = 0;
int tablaTempo = 240; // adjust to sync with melody

int[] tablaPattern = {
    60, 59, 60, 61,  // Dha - Ge - Dha - Tin
    60, 59, 60, 63   // Dha - Ge - Dha - Na
};

for (int i = 0; i < 180; i++)  // approx for 3 min
{
    foreach (int tablaNote in tablaPattern)
    {
        tablaTrack.Add(new NoteOnEvent(tablaTick, 9, tablaNote, 90, tablaTempo / 2));
        tablaTrack.Add(new NoteEvent(tablaTick + tablaTempo / 2, 9, MidiCommandCode.NoteOff, tablaNote, 0));
        tablaTick += tablaTempo;
    }
}

tablaTrack.Add(new MetaEvent(MetaEventType.EndTrack, 0, tablaTick + 100));Tabla tempo বা pattern আরও change করে specific রাগের lay বানাতে চেষ্টা করবো অবশ্যই।Advanced tabla pattern যোগ করার জন্য  MIDI percussion reference দেখে বিভিন্ন note (56–75 range) ব্যবহার করতে পারি হয়তো তবে শুনে দেখতে হবে।
Behag এর mood অনুযায়ী তবলার sound “খুলে” না গিয়ে soft + emotional হওয়াই ভালো।
 Behag এর full updated C# ফাইল (গিটার + তবলা সহ) তোমার জন্য paste করতে চেষ্টা করা উচিত ।
এছাড়াও আমি এর পর Bageshree, Darbari, Desh, Yaman  এগুলোও এভাবে বানিয়ে দেখবো ।

______________

Try 3+

 নিচে আমি Behag রাগের জন্য একটি প্রফেশনাল guitar strumming pattern সহ MIDI জেনারেটর sample code দিচ্ছি C#-এ, যেখানে 6টি চ্যানেলে বিভিন্ন গিটার ধ্বনি বাজবে, কিছু চ্যানেল শুধু strumming করবে, কিছু lead style বাজাবে, এবং সবকিছু tempo অনুযায়ী সাজানো থাকবে।এছাড়াও এই প্রোগ্রাম টি তে আমি Modulation, Pitch Bend, Velocity Variation, Proper Note Duration, এবং Program Change দিয়ে realistic effect এনেছি। চেষ্টা করছি অন্তত।
Behag Guitar Strumming MIDI Generator (NAudio + C#)

using NAudio.Midi;
using System;
using System.Collections.Generic;
using System .IO;

class BehagGuitarStrumming
{
    static List<int> scaleNotes = new List<int> {
        60, 62, 64, 65, 67, 69, 71, 72, // Ascending
        71, 69, 67, 65, 64, 62, 60       // Descending
    };

    static Dictionary<int, int> noteDurations = new Dictionary<int, int>
    {
        { 60, 500 }, { 62, 450 }, { 64, 400 },
        { 65, 500 }, { 67, 420 }, { 69, 400 },
        { 71, 430 }, { 72, 550 }
    };

    static int GetVelocity(int note)
    {
        Random rand = new Random();
        return Math.Clamp(105 - ((note - 60) * 2) + rand.Next(-8, 8), 70, 127);
    }

    static void Main()
    {
        var midiEvents = new MidiEventCollection(1, 480);
        var rand = new Random();

        int[] guitarPrograms = { 24, 25, 26, 27, 25, 26 }; // Nylon, Steel, Jazz, Clean

        for (int ch = 0; ch < 6; ch++)
        {
            var track = new List<MidiEvent>();
            midiEvents.AddTrack(track);

            int tick = 0;
            track.Add(new PatchChangeEvent(0, ch, guitarPrograms[ch]));

            if (ch < 2)
            {
                // Strumming channel
                for (int i = 0; i < 60; i++)
                {
                    int baseNote = scaleNotes[rand.Next(scaleNotes.Count)];
                    int[] chord = { baseNote, baseNote + 4, baseNote + 7 }; // Major chord
                    int vel = GetVelocity(baseNote);

                    foreach (int n in chord)
                    {
                        track.Add(new NoteOnEvent(tick, ch, n, vel, 120));
                        track.Add(new NoteEvent(tick + 120, ch, MidiCommandCode.NoteOff, n, 0));
                    }

                    tick += 240; // 1 beat strum
                }
            }
            else if (ch < 5)
            {
                // Lead melody channel
                for (int i = 0; i < scaleNotes.Count; i++)
                {
                    int note = scaleNotes[i];
                    int vel = GetVelocity(note);
                    int duration = noteDurations[note] + rand.Next(-20, 50);
                    int ticks = (int)(duration / 2.5);

                    track.Add(new ControlChangeEvent(tick, ch, MidiController.Modulation, rand.Next(40, 90)));
                    track.Add(new PitchWheelChangeEvent(tick, ch, rand.Next(3000, 9000)));

                    track.Add(new NoteOnEvent(tick, ch, note, vel, ticks));
                    track.Add(new NoteEvent(tick + ticks, ch, MidiCommandCode.NoteOff, note, 0));

                    tick += ticks + rand.Next(20, 80);
                }
            }
            else
            {
                // Bass channel or rhythm filler
                for (int i = 0; i < 40; i++)
                {
                    int note = scaleNotes[rand.Next(3)]; // lower notes only
                    int vel = GetVelocity(note) - 10;
                    int ticks = 160;

                    track.Add(new NoteOnEvent(tick, ch, note - 12, vel, ticks));
                    track.Add(new NoteEvent(tick + ticks, ch, MidiCommandCode.NoteOff, note - 12, 0));
                    tick += 320;
                }
            }

            track.Add(new MetaEvent(MetaEventType.EndTrack, 0, tick + 200));
        }

        string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Behag_Guitar_Strumming.mid");
        MidiFile.Export(fileName, midiEvents);
        Console.WriteLine("Behag Guitar MIDI with Strumming saved to: " + fileName);
    }
}

তৈরি হওয়া এই MIDI ফাইলটি

Behag রাগের স্বাদ বজায় রেখে melodic & harmonic parts গঠিত
6টি চ্যানেলে প্লে হবে
2টা Strumming Guitar (Nylon, Steel)
2টা Lead Guitar (Jazz, Clean)
1টা Bass Guitar
1টা Fill/String Guitar
Chords
Basic major chord progression (optional behag flavoring)
Effects
 Channel modulation, pitch wheel, varying velocity
পরবর্তী ধাপ এর চেষ্টা।
 আমি এই MIDI ফাইলে tabla/percussion loop যোগ করেও দেখতে হবে ।অথবা Behag-এর আরেকটা pure classical version চেষ্টা করতে পারি (no chords, just melody)

_________

Try 3++

 যদি Behag বা যেকোনো রাগ guitar এ 6টি চ্যানেলে বাজাতে চাই, তাহলে প্রোগ্রাম টি তে কিছু পরিবর্তন দরকার হবে

কী কী পরিবর্তন দরকার?

1. Instrument Patch (Program Change)

Flute এর জন্য আমরা 73 ব্যবহার করেছিলাম (MIDI Program 73 = Flute)

Guitar এর জন্য patch number এ এগুলো ব্যবহার করতে পারি 
24: Nylon Guitar
25: Steel Guitar
26: Jazz Guitar
27: Clean Electric Guitar
(একাধিক চ্যানেলে আলাদা গিটার tone দিতে পারো)

2. Velocity ও Duration Tuning

Guitar এর pluck effect তুলনামূলক দ্রুত decay হয় flute এর তুলনায়
Velocity একটু বেশি হলে ভালো লাগে (80-120 range)
Duration তুলনামূলক ছোট রাখতে হবে (150ms - 800ms)
3. Breath Controller (CC2) বাদ দিতে হবে
Breath guitar এর জন্য applicable না

4. Channel Pressure রাখা যেতে পারে, but optionally
Guitar expression এর জন্য অনেকসময় Modulation (CC1) ও Expression (CC11) ব্যবহার হয়

এই নতুন চেষ্টায় পরিবর্তিত C# NAudio Code (Behag on 6-Channel Guitar)

using NAudio.Midi;
using System;
using System.Collections.Generic;
using System.IO;

class BehagGuitarMidiGenerator
{
    static Dictionary<int, int> behagNoteDurations = new Dictionary<int, int>
    {
        { 60, 500 },  // Sa
        { 62, 400 },  // Re
        { 64, 350 },  // Ga
        { 65, 500 },  // Ma
        { 67, 450 },  // Pa
        { 69, 400 },  // Dha
        { 71, 420 },  // Ni
        { 72, 500 }   // Sa (higher)
    };

    static List<int> behagNotes = new List<int>
    {
        60, 62, 64, 65, 67, 69, 71, 72,
        71, 69, 67, 65, 64, 62, 60
    };

    static int GetVelocity(int noteNumber)
    {
        Random rand = new Random();
        int baseVelocity = 110 - ((noteNumber - 60) * 2);
        return Math.Clamp(baseVelocity + rand.Next(-10, 10), 70, 127);
    }

    static void Main()
    {
        var midiEventCollection = new MidiEventCollection(1, 480);
        int[] guitarPatches = { 24, 25, 26, 27, 24, 25 }; // Nylon, Steel, Jazz, Clean etc.
        var rand = new Random();

        for (int channel = 0; channel < 6; channel++)
        {
            var track = new List<MidiEvent>();
            midiEventCollection.AddTrack(track);

            track.Add(new PatchChangeEvent(0, channel, guitarPatches[channel]));

            int tick = 0;

            for (int i = 0; i < 14; i++)
            {
                int note = behagNotes[rand.Next(behagNotes.Count)];
                int durationMs = behagNoteDurations[note] + rand.Next(-30, 60);
                int velocity = GetVelocity(note);
                int durationTicks = (int)(durationMs / 2.5);

                // Optional: Use Modulation instead of Breath
                track.Add(new ControlChangeEvent(tick, channel, MidiController.Modulation, rand.Next(20, 80)));

                // Pitch Bend
                track.Add(new PitchWheelChangeEvent(tick, channel, rand.Next(4000, 9000)));

                // Note On
                track.Add(new NoteOnEvent(tick, channel, note, velocity, durationTicks));

                // Note Off
                track.Add(new NoteEvent(tick + durationTicks, channel, MidiCommandCode.NoteOff, note, 0));

                tick += durationTicks + rand.Next(20, 100);
            }

            // End Track
            track.Add(new MetaEvent(MetaEventType.EndTrack, 0, tick + 120));
        }

        string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Behag_Guitar_6_Channel.mid");
        MidiFile.Export(filePath, midiEventCollection);
        Console.WriteLine($"Saved Behag Guitar MIDI: {filePath}");
    }
}

chord ধরার জন্য কিছু চ্যানেল এ একসাথে multiple notes বাজাতে চেষ্টা করেছি try 3+ এ(strumming effect) এবং আরও depth আনতে চাইলে আমি "slide", "hammer-on", "string bend" effect simulate করেও চেষ্টা করতে পারি (MIDI CC ব্যবহার করে)।এইবার আমি Behag রাগের rhythmic guitar strumming with tabla loop MIDI বানিয়েও দেখবো try 3+ এ।

_______________

Try 6

নিচে Behag রাগ এর জন্য C# এবং NAudio ব্যবহার করে MIDI ফাইল জেনারেট করার সম্পূর্ণ কোড দিচ্ছি। এতে চেষ্টা করছি 
Behag স্কেল অনুযায়ী সঠিক নোট সিকোয়েন্স
6টি চ্যানেল ব্যবহার
Pitch Bend, Channel Pressure, Breath Control
Variation in note duration and velocity
MIDI ফাইল হিসেবে সেভ হবে
Behag Raga Flute MIDI Generator (6-Channel, Expressive)

using NAudio.Midi;
using System;
using System.Collections.Generic;
using System.IO;

class BehagFluteMidiGenerator
{
    static Dictionary<int, int> behagNoteDurations = new Dictionary<int, int>
    {
        { 60, 1000 },  // Sa
        { 62, 600 },   // Re
        { 64, 500 },   // Ga
        { 65, 1000 },  // Ma
        { 67, 900 },   // Pa
        { 69, 600 },   // Dha
        { 71, 700 },   // Ni
        { 72, 1000 }   // Sa (higher)
    };

    static List<int> behagNotes = new List<int>
    {
        60, 62, 64, 65, 67, 69, 71, 72,
        71, 69, 67, 65, 64, 62, 60
    };

    static int GetVelocity(int noteNumber)
    {
        Random rand = new Random();
        int baseVelocity = 100 - ((noteNumber - 60) * 2);
        return Math.Clamp(baseVelocity + rand.Next(-10, 10), 60, 127);
    }

    static void Main()
    {
        var midiEventCollection = new MidiEventCollection(1, 480); // Format 1
        int channelCount = 6;
        var rand = new Random();

        for (int channel = 0; channel < channelCount; channel++)
        {
            var track = new List<MidiEvent>();
            midiEventCollection.AddTrack(track);

            track.Add(new PatchChangeEvent(0, channel, 73)); // Flute

            int tick = 0;

            for (int i = 0; i < 12; i++)
            {
                int note = behagNotes[rand.Next(behagNotes.Count)];
                int durationMs = behagNoteDurations[note] + rand.Next(-50, 70);
                int velocity = GetVelocity(note);
                int pitchBend = rand.Next(3000, 10000);
                int durationTicks = (int)(durationMs / 2.5); // Rough

                // Channel Pressure (Breath feel)
                track.Add(new ChannelAfterTouchEvent(tick, channel, (byte)rand.Next(60, 100)));

                // Pitch Bend
                track.Add(new PitchWheelChangeEvent(tick, channel, pitchBend));

                // Note On
                track.Add(new NoteOnEvent(tick, channel, note, velocity, durationTicks));

                // Breath Control (CC 2)
                track.Add(new ControlChangeEvent(tick + 10, channel, MidiController.BreathController, rand.Next(60, 110)));

                // Note Off
                track.Add(new NoteEvent(tick + durationTicks, channel, MidiCommandCode.NoteOff, note, 0));

                tick += durationTicks + rand.Next(30, 120);
            }

            // End of track
            track.Add(new MetaEvent(MetaEventType.EndTrack, 0, tick + 120));
        }

        string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Behag_Flute_6_Channel.mid");
        MidiFile.Export(filePath, midiEventCollection);

        Console.WriteLine($"Saved Behag MIDI on: {filePath}");
    }
}

Behag স্কেল সম্পর্কে সংক্ষেপে
Behag রাগ সাধারণত ব্যবহার করে:
Aroha: Ni Sa Ga Ma Pa Ni Sa (no Re)
Avaroha: Sa Ni Dha Pa Ma Ga Re Sa
চলতি ফিচারস

6 Channel Flute
Randomized expressive velocity & duration
Breath Control (CC2) & Channel Pressure
Human feel pitch bends

প্রোগ্রাম টা চালানোর জন্য
1. Visual Studio তে একটি Console Project তৈরি কর 
2. NuGet থেকে NAudio ইনস্টল করা 
Install-Package NAudio
3. এই কোডটি Program.cs এ বসাও ও রান করো

MIDI ফাইল Behag_Flute_6_Channel.mid নামে Desktop এ পাওয়া যাবে।আরও ঠাট বা রাগ ওথবা Behag-এ আরও depth (Jhala, Sargam, Meend),  বানিয়ে দেখতে হবে।Behag-এর জন্য খুব ধীরে Alaap বা ঝিম সুরেও চেষ্টা করা যেতে পারে 

_______________

Try 6+
এইবার ভৈরবী ঠাট অনুযায়ী flute এর জন্য একটি সম্পূর্ণ C# কোড লিখে চেষ্টা করছি যাতে সেই প্রোগ্রাম টা 

NAudio ব্যবহার করে
6টি চ্যানেলে চালায়
Velocity ও Duration human-like expressive করে
Channel Pressure, Pitch Bend, Breath Control ইত্যাদি যোগ করে
প্রোগ্রাম টা একটি MIDI ফাইলে save করে

NAudio MIDI
 Bhairavi Raga Flute Performance (6-Channel, Expressive)

using NAudio.Midi;
using System;
using System.Collections.Generic;
using System.IO;

class BhairaviFluteMidiGenerator
{
    static Dictionary<int, int> bhairaviNoteDurations = new Dictionary<int, int>
    {
        { 60, 900 },  // Sa
        { 61, 300 },  // Komal Re
        { 63, 350 },  // Komal Ga
        { 65, 800 },  // Ma
        { 67, 900 },  // Pa
        { 68, 350 },  // Komal Dha
        { 70, 400 },  // Komal Ni
    };

    static int GetVelocity(int noteNumber)
    {
        // Expressive dynamic based on pitch: higher pitch, softer velocity
        Random rand = new Random();
        int baseVelocity = 100 - ((noteNumber - 60) * 3);
        return Math.Clamp(baseVelocity + rand.Next(-10, 10), 50, 127);
    }

    static void Main()
    {
        var midiEventCollection = new MidiEventCollection(1, 480); // Format 1, 480 ticks per beat
        int channelCount = 6;
        int trackIndex = 0;

        var random = new Random();
        var notes = new List<int> { 60, 61, 63, 65, 67, 68, 70 }; // Bhairavi scale
        int currentTick = 0;

        for (int channel = 0; channel < channelCount; channel++)
        {
            var track = new List<MidiEvent>();
            midiEventCollection.AddTrack(track);

            track.Add(new PatchChangeEvent(0, channel, 73)); // Flute instrument

            int tick = 0;

            for (int i = 0; i < 20; i++)
            {
                int note = notes[random.Next(notes.Count)];
                int durationMs = bhairaviNoteDurations[note] + random.Next(-50, 50);
                int velocity = GetVelocity(note);
                int pitchBend = random.Next(2000, 10000);
                int durationTicks = (int)(durationMs / 2.5); // Approximation

                // Channel pressure (Breath control effect)
                track.Add(new ChannelAfterTouchEvent(tick, channel, (byte)random.Next(50, 100)));

                // Pitch bend (expressive glide)
                track.Add(new PitchWheelChangeEvent(tick, channel, pitchBend));

                // Note On
                track.Add(new NoteOnEvent(tick, channel, note, velocity, durationTicks));

                // Breath Control (CC 2)
                track.Add(new ControlChangeEvent(tick + 10, channel, MidiController.BreathController, random.Next(40, 100)));

                // Note Off
                track.Add(new NoteEvent(tick + durationTicks, channel, MidiCommandCode.NoteOff, note, 0));

                tick += durationTicks + random.Next(20, 80); // Add rest
            }

            // End of track
            track.Add(new MetaEvent(MetaEventType.EndTrack, 0, tick + 120));
        }

        string outputPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Bhairavi_Flute_6_Channel.mid");
        MidiFile.Export(outputPath, midiEventCollection);

        Console.WriteLine($"MIDI file saved to: {outputPath}");
    }
}

মিডি তে Programming Features Explained

Channel Pressure
ChannelAfterTouchEvent simulates breathing effort
Pitch Bend
 Gives flute-style natural bends
Breath Control (CC2)
 Simulates breath intensity (only some synths respond)
Velocity
 Soft/hard note hit simulation
6 Channels
 Can be routed to 6 flute layers with slight variation for realism
Duration
Controlled by real Bhairavi aesthetics + randomness
Run Instructions
1. Install NAudio via NuGet
Install Package NAudio
2. Compile and run the code. It will save Bhairavi_Flute_6_Channel.mid on your Desktop.
Next Step
আমি এই কোডটাকে extend করে Behag বা অন্য ঠাটে নিয়ে যাবো এবং আরও প্রোগ্রামিং করে করে রাগিক অভিব্যক্তি (gamaka, meend, staccato vs sustain) যোগ করে চেষ্টা করবো আরো।

________________

Try 8

অবশ্যই! এখন আমি তোমাকে MIDI note duration নির্ণয় করার নিয়মগুলো ব্যাখ্যা করব এবং তার জন্য প্রয়োজনীয় durationRules ডিকশনারি ও কোড দিয়ে দেব। এতে করে তুমি ভিন্ন ঠাটে বা রাগে, ভিন্ন note-এর জন্য সময় (মিলিসেকেন্ড) কত হবে সেটা নির্ধারণ করতে পারবে।

---

১. Duration Calculation মূল ধারণা:

MIDI note duration (মিলিসেকেন্ডে) বিভিন্ন বিষয়ের উপর নির্ভর করে:

রাগের mood বা tempo (ধীর/মধ্য/দ্রুত)

note-এর position (Sa, Re, Ga... কোনটা কতটা গুরুত্ব পায়)

phrase structure (sustain, ornamentation, glide ইত্যাদি)

human playability (flute-এ কত ক্ষণ একটা note ধরা সম্ভব)

আমরা এই জন্য একটি সাধারণ রেঞ্জ ধরতে পারি:

Main Notes (Vadi/Samvadi): 600–1000 ms

Passing Notes (Alpatva): 200–400 ms

Grace/Ornamental Notes (Kan Swar): 100–200 ms

Rest or Deliberate Silence: 300–800 ms

---

২. C# Dictionary: Note Duration Map (Per Thaat or Raga)

উদাহরণ: ভৈরবী ঠাট এর জন্য duration mapping

var bhairaviDurationMap = new Dictionary<int, int>
{
    { 60, 900 },  // Sa
    { 61, 300 },  // Komal Re
    { 63, 350 },  // Komal Ga
    { 65, 800 },  // Ma
    { 67, 900 },  // Pa
    { 68, 350 },  // Komal Dha
    { 70, 400 },  // Komal Ni
};

---

উদাহরণ: বিলাওল ঠাট

var bilawalDurationMap = new Dictionary<int, int>
{
    { 60, 800 },  // Sa
    { 62, 700 },  // Re
    { 64, 700 },  // Ga
    { 65, 750 },  // Ma
    { 67, 800 },  // Pa
    { 69, 750 },  // Dha
    { 71, 700 }   // Ni
};

---

৩. একত্রিত সব ঠাটের জন্য master dictionary:

var thaatDurationMap = new Dictionary<string, Dictionary<int, int>>
{
    { "Bhairavi", bhairaviDurationMap },
    { "Bilawal", bilawalDurationMap },
    // Add more thaats as you define
};

---

৪. Helper Function:

int GetNoteDuration(string thaatName, int midiNote)
{
    if (thaatDurationMap.TryGetValue(thaatName, out var durationMap))
    {
        if (durationMap.TryGetValue(midiNote, out var duration))
        {
            return duration;
        }
    }

    return 400; // Default fallback duration in ms
}

---

৫. Example Usage (MIDI Event Timing):

int note = 60; // C (Sa)
int velocity = GetVelocity("Bhairavi", note);
int duration = GetNoteDuration("Bhairavi", note);

// Add to MIDI track
track.AddNoteOnEvent(channel, note, velocity, currentTime);
track.AddNoteOffEvent(channel, note, 0, currentTime + duration);

---

৬. চাইলেই Human-like Fluctuation যোগ করতে পারো:

Random rand = new Random();
int fluctuation = rand.Next(-50, 50); // Slight tempo variation
duration += fluctuation;
velocity += rand.Next(-10, 10); // Slight volume variation

, আমি বাকি ঠাট গুলোর duration dictionary ও লিখে চেষ্টা করতে হবে।তারপর তুমি এগুলো দিয়ে full expressive MIDI বানাতে হবে। এইবার আমি ভৈরবী ঠাট এর পুরো MIDI  কোড এ integrate করে  updated velocity + duration সহ, professional articulation সহ চেষ্টা করবো আর ও।

_______________

Try 9

অবশ্যই! নিচে আমি প্রতিটি ঠাটের জন্য একটি C# Dictionary<int, int> দিয়ে উদাহরণ দিচ্ছি, যেখানে key হচ্ছে MIDI note number (যেমন 60 = Middle C), এবং value হচ্ছে velocity।
তুমি একে একে সব ঠাট এর dictionary বানিয়ে রাখতে পারো এবং প্রয়োজনমতো access করতে পারো।

---

১. ভৈরবী ঠাট (Bhairavi Thaat) Velocity Map:

var bhairaviThaatVelocityMap = new Dictionary<int, int>
{
    // S, r (komal), g (komal), M, P, d (komal), n (komal)
    { 60, 80 },  // Sa (C)
    { 61, 70 },  // Komal Re (C#)
    { 63, 75 },  // Komal Ga (D#)
    { 65, 85 },  // Ma (F)
    { 67, 90 },  // Pa (G)
    { 68, 75 },  // Komal Dha (G#)
    { 70, 78 },  // Komal Ni (A#)
};

---

২. কাল্যাণ ঠাট (Kalyan Thaat) Velocity Map:

var kalyanThaatVelocityMap = new Dictionary<int, int>
{
    { 60, 85 },  // Sa
    { 62, 90 },  // Re
    { 64, 95 },  // Ga
    { 66, 110 }, // Tivra Ma
    { 67, 90 },  // Pa
    { 69, 95 },  // Dha
    { 71, 100 }  // Ni
};

---

৩. মারওয়া ঠাট (Marwa Thaat) Velocity Map:

var marwaThaatVelocityMap = new Dictionary<int, int>
{
    { 60, 75 },  // Sa
    { 61, 65 },  // Komal Re
    { 64, 85 },  // Ga
    { 66, 100 }, // Tivra Ma
    { 67, 85 },  // Pa
    { 69, 90 },  // Dha
    { 71, 95 }   // Ni
};

---

৪. বিলাওল ঠাট (Bilawal Thaat) Velocity Map:

var bilawalThaatVelocityMap = new Dictionary<int, int>
{
    { 60, 85 },  // Sa
    { 62, 88 },  // Re
    { 64, 90 },  // Ga
    { 65, 95 },  // Ma
    { 67, 100 }, // Pa
    { 69, 95 },  // Dha
    { 71, 90 }   // Ni
};

---

৫. খাম্বাজ ঠাট (Khamaj Thaat) Velocity Map:

var khamajThaatVelocityMap = new Dictionary<int, int>
{
    { 60, 85 },  // Sa
    { 62, 88 },  // Re
    { 64, 90 },  // Ga
    { 65, 95 },  // Ma
    { 67, 98 },  // Pa
    { 69, 95 },  // Dha
    { 70, 80 }   // Komal Ni
};

---

তুমি যদি এভাবে প্রতিটি ঠাটের জন্য আলাদা Dictionary<int, int> বানিয়ে নাও, তাহলে কোডে সেগুলাকে একটা Dictionary<string, Dictionary<int, int>> হিসেবে একত্র করতে পারো:

var thaatVelocityMap = new Dictionary<string, Dictionary<int, int>>
{
    { "Bhairavi", bhairaviThaatVelocityMap },
    { "Kalyan", kalyanThaatVelocityMap },
    { "Marwa", marwaThaatVelocityMap },
    { "Bilawal", bilawalThaatVelocityMap },
    { "Khamaj", khamajThaatVelocityMap },
    // ... add more
};

---

Helper Function:

int GetVelocity(string thaatName, int midiNote)
{
    if (thaatVelocityMap.TryGetValue(thaatName, out var noteMap))
    {
        if (noteMap.TryGetValue(midiNote, out var velocity))
        {
            return velocity;
        }
    }

    return 80; // Default fallback velocity
}

বাকি ৫টা ঠাট এর mapওলিখতে হবেই।
এই structure দিয়ে এখন  pernote accurate velocity assign করতে  MIDI generationএরeffect দেখা যাবে।
 duration rules-এর guide টাও এখন লিখে দেখবো।

____________

Try 9+

এখন আমি তোমাকে বিভিন্ন ঠাটের জন্য Velocity Calculation এর নিয়মগুলো কোন নোটে কী রকম ভেলোসিটি দেওয়া যায়, সেটার একটা লিখিত ফর্মে ধারাবাহিক গাইডলাইন হিসেবে দিচ্ছি (টেবিল নয়)। এতে প্রতিটি ঠাটের মুড ও চরিত্র অনুযায়ী কোন নোটে কতটা শক্তি/তীব্রতা দেওয়া উচিত, সেটা বোঝা যাবে।

1. ভৈরবী ঠাট (Bhairavi)

ভাব: করুণ, কোমল, বিষণ্ন

Sa (Tonic): 75–85 (stable)
Komal Re, Komal Dha: 65–75 (soft, gliding)
Komal Ga, Komal Ni: 70–80 (gentle, emotional)
Ma, Pa: 80–90 (stable, but expressive)
Tivra Ma (if used rarely): 85–95 (sharp but brief emphasis)

2. কাল্যাণ ঠাট (Kalyan)

ভাব: দেবতা, ঐশ্বরিকতা, ভক্তি
Sa: 80–90
Re, Ga, Dha, Ni: 85–100 (shining)
Tivra Ma: 100–115 (high emphasis; centerpiece of the scale)
Pa: 85–95 (stability)

3. মারওয়া ঠাট (Marwa)
ভাব: রহস্যময়, উদ্বেগ, গোধূলি
Sa: 70–80 (uncertain, floating)
Re (Komal): 60–70 (tension, soft but haunting)
Ga, Dha: 75–85 (sharp entry)
Tivra Ma: 90–105 (directional)
Ni: 85–95

4. বিলাওল ঠাট (Bilawal)
ভাব: উদারতা, সরলতা, পবিত্রতা
Sa: 80–90 (clean base)
Re, Ga, Dha, Ni: 85–95 (happy energy)
Ma, Pa: 90–100 (uplifting)
5. খাম্বাজ ঠাট (Khamaj)
ভাব: প্রেম, নরম, অলংকারপূর্ণ
Sa: 80–90
Re, Ga: 85–95 (playful)
Komal Ni: 75–85 (soft landing)
Ma, Pa: 90–100
6. আসাবারি ঠাট (Asavari)
ভাব: উদাসীনতা, কষ্ট, কোমল অনুভব
Sa: 70–80
Komal Ga, Dha, Ni: 60–75 (deep expression)
Ma, Pa: 80–90
7. পুরবী ঠাট (Purvi)
ভাব: অলৌকিক, সন্ধ্যা-রহস্য, উচ্চ অনুভব
Sa: 75–85
Komal Re, Dha: 70–80
Tivra Ma: 100–110
Ga, Ni: 85–95
8. ভৈরব ঠাট (Bhairav)
ভাব: গম্ভীরতা, ভক্তি, ভয়-ভীতি
Sa: 80–90
Komal Re, Dha: 65–75
Ma, Pa, Ni: 85–95
9. তোড়ি ঠাট (Todi)
ভাব: পরিশীলিত, রহস্যময়, তীব্র অভিব্যক্তি
Sa: 70–80
Komal Re, Ga, Dha, Ni: 60–75
Tivra Ma: 100–115
10. কফি ঠাট (Kafi)
ভাব: নরম, মৃদু প্রেম, দোলপূর্ণ
Sa: 80–90
Komal Ga, Ni: 65–75
Ma, Pa, Dha: 85–95
ভারতীয় দের পছন্দ non perfections ফলে Extra random ধরনের additional Notes দরকার হয়।
Velocity এর মধ্যে variation রাখা natural human expression এর simulation এর জন্য ভালো।যদি একটু random ±10 range দেওয়া হয়, তাহলে সেই human imperfection আসে। এই ইনফারফেকশন টা ভারতীয় দের খুব পছন্দ। গাণিতিক ভাবে বোকা বোকা।

NAudio-তে velocity = GetVelocityForThaatAndNote(thaat, midiNote) এইরকম function করে রাখলে  কোড টা modular হয়। প্রতিটা ঠাটের জন্য একটা Dictionary<string, int> বানিয়ে দেখতে শুনতে পারি যেটা নোট নাম্বার অনুযায়ী velocity return করবে।

____________

Try 11

 Velocity এবং Note Duration (in milliseconds) নির্ধারণ করা রাগ বাজানোর সময় খুবই গুরুত্বপূর্ণ—এগুলো ঠিকঠাক না হলে sound কৃত্রিম বা unmusical শোনায়।
1. Velocity Calculation Rule (MIDI)

MIDI Velocity Range

0 – 127:
0 = no sound
127 = maximum force/loudness
Behag বা Bhairavi র মতো soft রাগে সাধারণত
Velocity Range: 60 – 110
Soft expressive parts → 60–80
Bold or emphasized parts (like high Sa or Pa) → 90–110
Velocity Calculation Heuristic
velocity = (int)(baseVelocity + (durationMs / 10) + (pitch / 3)) % 127;

Example

Higher pitched notes naturally sound louder, so we increase velocity slightly.
Longer notes usually played more expressively → slightly more velocity.
Or, we can add randomness with bounds

int velocity = rnd.Next(70, 110);

If you want more control:

int pitch = 72; // C5
int durationMs = 600;

int velocity = 70 + (durationMs / 20) + ((pitch - 60) / 2); // You can tune the constants
if (velocity > 127) velocity = 127;

2. Note Duration Calculation Rule (ms)
MIDI তে duration হিসাব হয়
ticksPerQuarterNote = 480 (standard)

Then,use

durationTicks = (int)((durationMs / 1000.0) * bpm * ticksPerQuarterNote / 60);

Example:

int bpm = 90;
int durationMs = 600;

int durationTicks = (int)((600 / 1000.0) * 90 * 480 / 60);
// = (0.6) * 90 * 8
// = ~432 ticks

Duration Based on Raga Feeling
Restful Notes (Sa, Pa) → Longer: 600ms–1000ms
Moving Notes (Re, Ga, Dha) → Shorter: 250ms–500ms
Gamaka or fast transition → Very short: 120–200ms
General Heuristic Code Example

int note = 72;
bool isRestNote = (note % 12 == 0 || note % 12 == 7); // Sa or Pa
int durationMs = isRestNote ? rnd.Next(600, 900) : rnd.Next(300, 600);

একটি auto calculated velocity & duration helper class তৈরি করে দেখা টা রিসার্চ, যেটা automated raga MIDI generator এ ব্যবহার করতে চেষ্টা করছি।

______________

Try 11+

প্রোগ্রামিং করার জন্য NAudio C# দিয়ে রাগ বেহাগ (Behag) এর ৩ মিনিটের একটি প্রোফেশনাল MIDI ফাইল তৈরির কোড তৈরি করব 

৬টি চ্যানেল ব্যবহার করে
Pure Flute sound (MIDI Program 73)
Pitch Bend, Channel Pressure, Breath Control, Volume Fade, Strumming, Panning সহ সম্পূর্ণ effect দেয়
সুন্দর Stereo Imaging তৈরি করে
শুনলে প্রফেশনাল লাইভ ফ্লুট রেন্ডিশনের মত শোনাবে
Behag Raga MIDI Generator (NAudio C# Pro Version)

using System;
using System.IO;
using NAudio.Midi;

class BehagMidiFlutePro
{
    static void Main()
    {
        string outputPath = "BehagFlute_Effect.mid";
        var midiEventCollection = new MidiEventCollection(1, 480);

        int bpm = 95;
        int ticksPerBeat = 480;

        // Raga Behag (approx. notes used)
        // Aroha: S G M P N S’
        // Avaroha: S’ N D P M G R S
        // Behag uses both shuddha and teevra notes depending on the phrasing
        int[] behagNotes = { 60, 64, 65, 67, 71, 72, 74, 69, 68, 65, 64, 62, 60 };

        Random rnd = new Random();

        for (int channel = 0; channel < 6; channel++)
        {
            midiEventCollection.AddTrack();
            midiEventCollection[channel].Add(new PatchChangeEvent(0, channel, 73)); // Flute

            int currentTime = 0;

            for (int i = 0; i < 150; i++) // approx 3 minutes of music
            {
                int note = behagNotes[rnd.Next(behagNotes.Length)];
                int velocity = rnd.Next(70, 110);
                int duration = rnd.Next(300, 800); // between 300ms to 800ms
                int strumDelay = channel * 15;

                // Pitch bend (±1500)
                int pitchBend = 8192 + rnd.Next(-1500, 1500);
                midiEventCollection[channel].Add(new PitchWheelChangeEvent(currentTime, channel, pitchBend));

                // Channel Pressure
                midiEventCollection[channel].Add(new ChannelAfterTouchEvent(currentTime, channel, rnd.Next(50, 120)));

                // Breath Control (CC 2)
                midiEventCollection[channel].Add(new ControlChangeEvent(currentTime, channel, MidiController.BreathController, rnd.Next(60, 120)));

                // Volume fade (CC 7)
                int volume = 100 - (i % 15);
                midiEventCollection[channel].Add(new ControlChangeEvent(currentTime, channel, MidiController.MainVolume, volume));

                // Panning (CC 10)
                int pan = 30 + channel * 14;
                midiEventCollection[channel].Add(new ControlChangeEvent(currentTime, channel, MidiController.Pan, pan));

                // Note On
                midiEventCollection[channel].Add(new NoteOnEvent(currentTime + strumDelay, channel, note, velocity, duration));

                // Note Off
                midiEventCollection[channel].Add(new NoteEvent(currentTime + duration + strumDelay, channel, MidiCommandCode.NoteOff, note, 0));

                currentTime += duration;
            }
        }

        MidiFile.Export(outputPath, midiEventCollection);
        Console.WriteLine("Behag MIDI file generated: " + outputPath);
    }
}

_________

Try 11++

এইবার sample রূপে নিচে দেওয়া হলো পূর্ণাঙ্গ NAudio C# কোড, যেটি

ভৈরবী রাগ এর ৩ মিনিটের MIDI ফাইল তৈরি করে
Flute (Program 73) 6টি চ্যানেলে বাজায়
Pitch bend, Channel Pressure, Breath Control (CC 2)
Strumming effect (slight delay between simultaneous notes)
Volume fading (CC 7)
Panning (CC 10)
পুরো ফাইলটি সুন্দরভাবে ব্যালেন্সড করে

Full Pro Level C# Code: Bhairavi MIDI (With Effects)

using System;
using System.IO;
using NAudio.Midi;

class BhairaviMidiProFlute
{
    static void Main()
    {
        string outputPath = "BhairaviFlute_Effect.mid";
        var midiEventCollection = new MidiEventCollection(1, 480);

        int bpm = 90;
        int ticksPerBeat = 480;
        int msPerTick = (60000 / bpm) / ticksPerBeat;

        // Bhairavi Notes (Sa, Komal Re, Komal Ga, Ma, Pa, Komal Dha, Komal Ni, Sa)
        int[] bhairaviNotes = { 60, 61, 63, 65, 67, 68, 70, 72 };

        Random rnd = new Random();

        for (int channel = 0; channel < 6; channel++)
        {
            int track = channel;
            midiEventCollection.AddTrack();

            // Set Instrument - Flute (73)
            midiEventCollection[track].Add(new PatchChangeEvent(0, channel, 73));

            int currentTime = 0;

            for (int i = 0; i < 150; i++) // ~150 notes x avg 1.2s = ~3 min
            {
                int noteIndex = rnd.Next(bhairaviNotes.Length);
                int note = bhairaviNotes[noteIndex];
                int velocity = rnd.Next(70, 120);
                int duration = rnd.Next(240, 960); // variable durations

                // Pitch bend (±2000 random)
                int pitch = 8192 + rnd.Next(-2000, 2000);
                midiEventCollection[track].Add(new PitchWheelChangeEvent(currentTime, channel, pitch));

                // Channel Pressure
                midiEventCollection[track].Add(new ChannelAfterTouchEvent(currentTime, channel, rnd.Next(40, 127)));

                // Breath Control (CC 2)
                midiEventCollection[track].Add(new ControlChangeEvent(currentTime, channel, MidiController.BreathController, rnd.Next(50, 127)));

                // Volume Fade (CC 7)
                int volume = 100 - (i % 20); // fade out effect
                midiEventCollection[track].Add(new ControlChangeEvent(currentTime, channel, MidiController.MainVolume, volume));

                // Panning (CC 10)
                int pan = 32 + (channel * 12); // stereo separation
                midiEventCollection[track].Add(new ControlChangeEvent(currentTime, channel, MidiController.Pan, pan));

                // Strumming delay (each channel slightly delayed)
                int strumDelay = channel * 20;

                // Note On
                midiEventCollection[track].Add(new NoteOnEvent(currentTime + strumDelay, channel, note, velocity, duration));

                // Note Off
                currentTime += duration;
                midiEventCollection[track].Add(new NoteEvent(currentTime + strumDelay, channel, MidiCommandCode.NoteOff, note, 0));
            }
        }

        MidiFile.Export(outputPath, midiEventCollection);
        Console.WriteLine("MIDI file generated: " + outputPath);
    }
}

______________

Try 11+++

এইবার নিচে ৩ মিনিটের জন্য একটি ভৈরবী রাগ MIDI ফাইল তৈরি করার সম্পূর্ণ C# কোড দিচ্ছি, যেটা

C sharp এর NAudio ব্যবহার করে
6 টি চ্যানেলে flute এর ভিন্ন ভিন্ন নোট বাজায়
প্রতিটি নোটে ভিন্ন duration, pitch bend, channel pressure ও breath control (CC #2) প্রয়োগ করে
MIDI instrument: Flute (Program 73)
Total duration: 3 minutes
Output: .mid ফাইল হিসেবে save হবে
এই C# কোড (NAudio দিয়ে MIDI ফাইল তৈরি)

using System;
using System.IO;
using NAudio.Midi;

class BhairaviMidiGenerator
{
    static void Main()
    {
        string outputPath = "BhairaviFlute.mid";
        var midiEventCollection = new MidiEventCollection(1, 480);

        // Bhairavi raga notes (Sa, Komal Re, Komal Ga, Ma, Pa, Komal Dha, Komal Ni, Sa)
        int[] bhairaviNotes = { 60, 61, 63, 65, 67, 68, 70, 72 };

        int bpm = 90;
        int ticksPerBeat = 480;
        int msPerTick = (60000 / bpm) / ticksPerBeat;

        Random rnd = new Random();

        for (int channel = 0; channel < 6; channel++)
        {
            int track = channel;
            midiEventCollection.AddTrack();

            // Set Instrument to Flute (Program Number 73)
            midiEventCollection[track].Add(new PatchChangeEvent(0, channel, 73));
            
            int currentTime = 0;

            for (int i = 0; i < bhairaviNotes.Length * 20; i++)
            {
                int noteIndex = i % bhairaviNotes.Length;
                int noteNumber = bhairaviNotes[noteIndex];
                int velocity = rnd.Next(70, 110);
                int durationTicks = rnd.Next(240, 960); // Varying durations (0.5 to 2 beats)
                
                // Optional Pitch Bend (centered ±2000)
                int pitchBend = 8192 + rnd.Next(-2000, 2000);
                midiEventCollection[track].Add(new PitchWheelChangeEvent(currentTime, channel, pitchBend));

                // Channel Pressure
                midiEventCollection[track].Add(new ChannelAfterTouchEvent(currentTime, channel, rnd.Next(50, 120)));

                // Breath Control (CC 2)
                midiEventCollection[track].Add(new ControlChangeEvent(currentTime, channel, MidiController.BreathController, rnd.Next(40, 127)));

                // Note On
                midiEventCollection[track].Add(new NoteOnEvent(currentTime, channel, noteNumber, velocity, durationTicks));

                // Note Off
                currentTime += durationTicks;
                midiEventCollection[track].Add(new NoteEvent(currentTime, channel, MidiCommandCode.NoteOff, noteNumber, 0));
            }
        }

        MidiFile.Export(outputPath, midiEventCollection);
        Console.WriteLine($"MIDI file generated: {outputPath}");
    }
}

এগুলো চেষ্টা করার আগে
Visual Studio Console App তৈরি করুন
NuGet দিয়ে NAudio ইনস্টল করুন
Install-Package NAudio
BhairaviFlute.mid নামে ৩ মিনিটের MIDI ফাইল তৈরি হবে
এই কোডে delay effect, strumming simulation, volume fading, বা panning ও যোগ করে চেষ্টা করা উচিত 

______
Try 15

এখানে ভৈরবী রাগের MIDI তথ্য নিচে দেওয়া হলো (Pure Flute এর জন্য)
ভৈরবী রাগের স্বর (মধ্য সপ্তক)
Sa (C4) – MIDI: 60 – Frequency: 261.63 Hz
komal Re (C#4) – MIDI: 61 – Frequency: 277.18 Hz
komal Ga (D#4) – MIDI: 63 – Frequency: 311.13 Hz
Ma (F4) – MIDI: 65 – Frequency: 349.23 Hz
Pa (G4) – MIDI: 67 – Frequency: 392.00 Hz
komal Dha (G#4) – MIDI: 68 – Frequency: 415.30 Hz
komal Ni (A#4) – MIDI: 70 – Frequency: 466.16 Hz
Sa (C5) – MIDI: 72 – Frequency: 523.25 Hz
আমি NAudio ব্যবহার করে ভৈরবী রাগের একটি C# প্রোগ্রাম লিখেছি 

6টি channel ব্যবহার করে
প্রতিটি নোটে ভিন্ন duration
Pitch Bend, Channel Pressure ও Breath Control (CC #2) সহ শুধুমাত্র flute instrument (MIDI Program Number: 73)
এগুলো MIDI ফাইলে অবশ্যই সংরক্ষিত করতে হবে কারণ direct প্লে তে অনেক effect computer এ পাবেন না।

_________

Try 15+

 নিচে 10টি প্রধান ঠাট (Thaat) অনুযায়ী প্রত্যেকটি স্বরের MIDI Note Number এবং Frequency in Hertz (Hz) সহ একটি তালিকা তৈরি করে দেবো পরে। ধরে নিচ্ছি Sa = C4 (MIDI note 60 = 261.63 Hz) হিসাবে।

প্রত্যেক ঠাটে Sa, Re, Ga, Ma, Pa, Dha, Ni এই সাতটি স্বর থাকে এদের মধ্যেই কোনটা কোমল (♭) বা তীব্র (♯) সেটা বদলায়। 20 cent থেকে 100 cent পর্যন্ত।
Frequency & MIDI Note Reference Table তৈরি করছি। সময় লাগবে।(Hertz গুলো সমান তাপমাত্রা ও standard tuning A4=440Hz অনুযায়ী)
10 Principal Thaats with MIDI Note Numbers and Frequencies গুলো আলোচনা করতে হবে।

প্রতিটি ঠাটের MIDI ফাইল জেনারেট করে ও দেখতে পারি।
আলাদা আলাদা চ্যানেল এ ভিন্ন ঠাট বাজাতে পারি।
নির্দিষ্ট রাগ বা ঠাটের emotional expression অনুযায়ী pitch bend, velocity, pressure যোগ করতে পারি।

_________

Try 17

ভৈরবী রাগ (Bhairavi Raga) একটি মিষ্টি, মেলানকোলিক এবং devotional ধরণের রাগ। MIDI দিয়ে এটি রেন্ডার করতে চাইলে আমাদের কিছু জিনিস মাথায় রাখতে হবে
ভৈরবী রাগ  স্কেল (MIDI Note Numbers সহ)
NAudio দিয়ে MIDI File
 ভৈরবী রাগ Pure Flute (C# Code)

using NAudio.Midi;
using System;
using System.IO;
using System.Collections.Generic;

class BhairaviRagaMidi
{
    static void Main()
    {
        string filePath = "bhairavi_flute.mid";
        var midiEvents = new MidiEventCollection(1, 480);

        var trackEvents = new List<MidiEvent>();
        int channel = 0;
        int velocity = 90;
        int tick = 0;
        int noteLength = 480; // 1 beat at 120 BPM

        // Bhairavi Raga notes ascending & descending
        int[] bhairaviNotes = {
            60, 61, 63, 65, 67, 68, 70, 72, // Arohan
            72, 70, 68, 67, 65, 63, 61, 60  // Avarohan
        };

        foreach (int note in bhairaviNotes)
        {
            // Add pitch bend for vibrato feel (optional)
            trackEvents.Add(new PitchWheelChangeEvent(tick + 10, channel, 8192 + 300));
            trackEvents.Add(new PitchWheelChangeEvent(tick + 30, channel, 8192 - 300));
            trackEvents.Add(new PitchWheelChangeEvent(tick + 50, channel, 8192));

            // Breath Control for expression
            trackEvents.Add(new ControlChangeEvent(tick, channel, MidiController.BreathController, 100));

            // Channel Pressure
            trackEvents.Add(new ChannelAfterTouchEvent(tick + 5, channel, 70));

            // Note On
            trackEvents.Add(new NoteOnEvent(tick, channel, note, velocity, noteLength));
            // Note Off
            trackEvents.Add(new NoteEvent(tick + noteLength, channel, MidiCommandCode.NoteOff, note, 0));

            tick += noteLength + 30; // spacing between notes
        }

        // Add End of Track
        trackEvents.Add(new MetaEvent(MetaEventType.EndTrack, 0, tick + 100));

        // Add to MIDI collection
        midiEvents.AddTrack(trackEvents);

        // Export
        MidiFile.Export(filePath, midiEvents);
        Console.WriteLine("MIDI File saved: " + Path.GetFullPath(filePath));
    }
}

এই কোডে যা থাকছে

ভৈরবী রাগের আরোহ ও অবরোহ অনুযায়ী নোট প্লে করা হচ্ছে।প্রতি নোটে Pitch Bend, Channel Pressure ও Breath Controller যুক্ত করা হয়েছে।Pure Flute tone পেতে DAW এ General MIDI Channel 74 বা কোনো Flute VSTi সেট করা যাবে। এখানে noteLength parametrically permuted করে করে পরিবর্তন করে slow/fast ভৈরবী বানাতে হবে।

Vibrato আরও expressive করতে হবে ফলে PitchWheelChange আরও smooth করে চেষ্টা করছি। আমি MIDI তে alaap style বা রাগের মতো phrasing করে generate করবো পরে।  কী ধরনের emotion বা structure হবে তার vector রূপ ডিজাইন করতে হবে আগে।
_________
Try 18
এইবার তাহলে আমরা নিচের কাজগুলো করব

1. ৬টি চ্যানেলে ভিন্ন ভিন্ন ফ্লুট নোট প্লে করব ভিন্ন duration ও expression সহ।
2. Channel Pressure, Breath Control, Pitch Bend — এগুলো apply করব।
3. MIDI ফাইল তৈরি করব .mid format-এ NAudio দিয়ে।
NAudio দিয়ে MIDI ফাইল তৈরি করার সম্পূর্ণ C# কোড দেওয়া হচ্ছে 

using NAudio.Midi;
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string filePath = "flute_expression_layered.mid";
        var midiEventCollection = new MidiEventCollection(1, 480); // format 1, 480 ticks per quarter

        int[] channels = { 0, 1, 2, 3, 4, 5 };
        int[] notes = { 72, 74, 76, 77, 79, 81 }; // C5 → A5
        int[] velocities = { 100, 90, 110, 80, 105, 95 };
        int[] durations = { 300, 500, 700, 400, 600, 800 }; // in ms
        int tickPerMs = 480 / 500; // Assuming 120 BPM = 500 ms per quarter note

        for (int i = 0; i < channels.Length; i++)
        {
            int channel = channels[i];
            int note = notes[i];
            int velocity = velocities[i];
            int duration = durations[i];
            int startTick = 0;
            int endTick = duration * tickPerMs;

            var trackEvents = new TrackEventCollection();

            // Add Note On
            trackEvents.Add(new NoteOnEvent(startTick, channel, note, velocity, 0));

            // Add Breath Control (CC2)
            trackEvents.Add(new ControlChangeEvent(startTick, channel, MidiController.BreathController, 80));
            trackEvents.Add(new ControlChangeEvent(startTick + 20 * tickPerMs, channel, MidiController.BreathController, 100));

            // Add Channel Pressure
            trackEvents.Add(new ChannelAfterTouchEvent(startTick + 10 * tickPerMs, channel, 70));
            trackEvents.Add(new ChannelAfterTouchEvent(startTick + 30 * tickPerMs, channel, 90));

            // Add Pitch Bend (Vibrato)
            trackEvents.Add(new PitchWheelChangeEvent(startTick + 5 * tickPerMs, channel, 8192 + 512));
            trackEvents.Add(new PitchWheelChangeEvent(startTick + 15 * tickPerMs, channel, 8192 - 512));
            trackEvents.Add(new PitchWheelChangeEvent(startTick + 25 * tickPerMs, channel, 8192));

            // Add Note Off
            trackEvents.Add(new NoteEvent(endTick, channel, MidiCommandCode.NoteOff, note, 0));

            // Add End of Track
            trackEvents.Add(new MetaEvent(MetaEventType.EndTrack, 0, endTick + 100));

            // Add to master collection
            midiEventCollection.AddTrack(trackEvents);
        }

        MidiFile.Export(filePath, midiEventCollection);
        Console.WriteLine("MIDI file saved to: " + Path.GetFullPath(filePath));
    }
}
এই কোডে যা হচ্ছে
প্রতি চ্যানেলে একটি নোট প্লে হচ্ছে ভিন্ন duration সহ।
Breath Control (CC2), Channel Pressure, ও Pitch Bend পরিবর্তন হচ্ছে।
MIDI ফাইল flute_expression_layered.mid হিসেবে সেভ হচ্ছে।
 .mid ফাইলটা DAW (audacity,FL Studio, Reaper, etc.) তে ওপেন করে শুনতে পারি।

Flute sound পেতে DAW এ একটা ভাল VSTi বা GM Flute Instrument সেট করতে হয় আগেই প্রতিটা চ্যানেলে।Pitch bend range DAW এ 2 semitone করে রাখতে হয়, নাহলে pitch bend কাজ করবে না।
এইবার যদি parametrically auto generated permuted Indian ragas বা parametric emotional expression যুক্ত করতে চেষ্টা করি,  সেটাও MIDI প্রোগ্রাম করে চেষ্টা করতে পারি। 

_________
Try 19

  Memory overflow হচ্ছে post এর

No comments:

Post a Comment