KindElephant480
Asistan
- Katılım
 - 14 Eylül 2017
 
- Mesajlar
 - 379
 
- Reaksiyon puanı
 - 46
 
- Puanları
 - 28
 
1 yıldan fazla bir süredir NeoBleeper isimli SomethingUnreal kullanıcı adına sahip eski bir YouTuber'ın VB6 kullanarak geliştirdiği ve bilgisayarların anakartlarında bulunan sistem hoparlörü (normalde bilgisayarların sadece bip sesi çıkarması için kullanılan bir çeşit hoparlör) ile melodi çalmayı sağlayan Bleeper Music Maker programının C# dili ile yeniden yazdığım ve yapay zekâ destekli resimdeki yeniden yapımı olan bir program geliştiriyorum ancak listedeki notaları çalma özelliğini çalışır duruma getirdiğimden bu yana aşırı yavaş çalınma gibi çeşitli sorunlar yaşadım, bir süre sonra pencereyi gizleyene kadar aşırı yavaş çalınma sorunlarını çözdüm ancak videodaki gibi notaların uzunluklarının senkronize oynatmada senkronizasyonu bozacak şekilde hatalı hesaplandığını fark ettim ve sorunu System.Threading.Timers.Timer kullanan ve arayüz dondurmayan bekleme metodumdaki Timer'ı Stopwatch ile değiştirerek büyük oranda çözdüm.
Ancak videolardaki gibi iki programı karşılaştırdığımda orijinal Bleeper Music Maker programında notalar daha hızlı çalınırken NeoBleeper programımda orijinal Bleeper Music Maker programına göre daha yavaş çalındığını fark ettim ve bu kodlardaki yöntemler üzerinde sonuçları kesme veya yuvarlama işlemleri ve vuruş uzunluğu hesaplamaları konusunda denemeler yaptım ancak hiçbir sonuca ulaşamıyorum.
		C#:
	
	private async void play_music(int startIndex)
        {
            bool nonStopping = false;
            EnableDisableCommonControls(false);
            while (listViewNotes.SelectedItems.Count > 0 && is_music_playing)
            {
                nonStopping = trackBar_note_silence_ratio.Value == 100;
                // Calculating note length and line length based on BPM
                decimal millisecondsPerWholeNote = 0m;
                if (Variables.bpm > 0)
                {
                    // 60,000 ms / BPM = whole note duration in milliseconds / 240,000 ms = whole note duration in milliseconds for 4/4 time signature
                    millisecondsPerWholeNote = 240000m / Variables.bpm;
                }
                // Note length and line length calculators
                int noteLength = note_length_calculator((double)millisecondsPerWholeNote);
                int lineLength = line_length_calculator((double)millisecondsPerWholeNote);
                // Note duration and wait duration calculations should be at least 1 ms
                int calculatedNoteDuration = Math.Max(1, noteLength);
                // Line length should also be at least 1 ms
                int calculatedWaitDuration = Math.Max(calculatedNoteDuration, lineLength);
                // Silence duration calculation
                int silenceDuration = calculatedWaitDuration - calculatedNoteDuration;
                // Play with MIDI output if enabled
                if (Program.MIDIDevices.useMIDIoutput)
                {
                    play_note_in_line_from_MIDIOutput(
                        listViewNotes.SelectedIndices[0],
                        checkBox_play_note1_played.Checked,
                        checkBox_play_note2_played.Checked,
                        checkBox_play_note3_played.Checked,
                        checkBox_play_note4_played.Checked,
                        calculatedNoteDuration
                    );
                }
                // Regular note playing logic
                play_note_in_line(
                    checkBox_play_note1_played.Checked,
                    checkBox_play_note2_played.Checked,
                    checkBox_play_note3_played.Checked,
                    checkBox_play_note4_played.Checked,
                    calculatedNoteDuration,
                    nonStopping
                );
                // Apply the note length to the selected line in the ListView
                if (silenceDuration > 0 && !nonStopping)
                {
                    UpdateLabelVisible(false); // Hide the label
                    NonBlockingSleep.Sleep(silenceDuration);
                }
                // Select the next line in the ListView
                await UpdateListViewSelectionSync(startIndex);
            }
            // Clean up after playing
            if (nonStopping)
            {
                stopAllNotesAfterPlaying();
            }
            EnableDisableCommonControls(true);
        }
private int note_length_calculator(double msPerWholeNote)
        {
            if (listViewNotes.SelectedItems == null || listViewNotes.SelectedItems.Count == 0 ||
                listViewNotes.Items == null || listViewNotes.Items.Count == 0)
            {
                return 0;
            }
            int selectedLine = listViewNotes.SelectedIndices[0];
            string noteType = listViewNotes.Items[selectedLine].SubItems[0].Text;
            string modifier = listViewNotes.Items[selectedLine].SubItems[5].Text;
            string articulation = listViewNotes.Items[selectedLine].SubItems[6].Text;
            // Calculate the basic note length based on the note type
            decimal noteFraction = noteType switch
            {
                "Whole" => 1m,      // Whole note
                "Half" => 0.5m,     // Half note
                "Quarter" => 0.25m, // Quarter note
                "1/8" => 0.125m,    // 1/8 note
                "1/16" => 0.0625m,  // 1/16 note
                "1/32" => 0.03125m, // 1/32 note
                _ => 0.25m,         // Default: Quarter note
            };
            // Modifier factor (Dot, Triplet)
            decimal modifierFactor = 1m;
            if (!string.IsNullOrEmpty(modifier))
            {
                if (modifier.ToLowerInvariant().Contains("dot"))
                    modifierFactor = 1.5m; // Dotted note: 1.5x length
                else if (modifier.ToLowerInvariant().Contains("tri"))
                    modifierFactor = 1m / 3m; // Triplet: 1/3x length
            }
            // Articulation factor - only affects fermata
            decimal articulationFactor = 1m;
            if (!string.IsNullOrEmpty(articulation))
            {
                if (articulation.ToLowerInvariant().Contains("sta"))
                    articulationFactor = 0.5m;    // Staccato: 0.5x length
                else if (articulation.ToLowerInvariant().Contains("spi"))
                    articulationFactor = 0.25m;   // Spiccato: 0.25x length
                else if (articulation.ToLowerInvariant().Contains("fer"))
                    articulationFactor = 2m;      // Fermata: 2x length
            }
            // Note-silence ratio (from trackBar)
            decimal silenceRatio = (decimal)trackBar_note_silence_ratio.Value / 100m;
            // Calculate the total note length
            decimal result = (decimal)msPerWholeNote * noteFraction * modifierFactor * articulationFactor * silenceRatio;
            // Should be at least 1 ms
            return Math.Max(1, (int)Math.Round(result, MidpointRounding.AwayFromZero));
        }
private int line_length_calculator(double msPerWholeNote)
        {
            if (listViewNotes.SelectedItems == null || listViewNotes.SelectedItems.Count == 0 ||
                listViewNotes.Items == null || listViewNotes.Items.Count == 0)
            {
                return 0;
            }
            int selectedLine = listViewNotes.SelectedIndices[0];
            string noteType = listViewNotes.Items[selectedLine].SubItems[0].Text;
            string modifier = listViewNotes.Items[selectedLine].SubItems[5].Text;
            string articulation = listViewNotes.Items[selectedLine].SubItems[6].Text;
            // Calculate the basic note length based on the note type
            decimal noteFraction = noteType switch
            {
                "Whole" => 1m,      // Whole note
                "Half" => 0.5m,     // Half note
                "Quarter" => 0.25m, // Quarter note
                "1/8" => 0.125m,    // 1/8 note
                "1/16" => 0.0625m,  // 1/16 note
                "1/32" => 0.03125m, // 1/32 note
                _ => 0.25m,         // Default: Quarter note
            };
            // Modifier factor (Dot, Triplet)
            decimal modifierFactor = 1m;
            if (!string.IsNullOrEmpty(modifier))
            {
                if (modifier.ToLowerInvariant().Contains("dot"))
                    modifierFactor = 1.5m; // Dotted: 1.5x length
                else if (modifier.ToLowerInvariant().Contains("tri"))
                    modifierFactor = 1m / 3m; // Triplet: 1/3x length
            }
            // Articulation factor - only affects fermata
            decimal articulationFactor = 1m;
            if (!string.IsNullOrEmpty(articulation) && articulation.ToLowerInvariant().Contains("fer"))
            {
                articulationFactor = 2m; // Fermata: 2x length
            }
            // Staccato and Spiccato do not affect line length
            // Calculate the total line length (without note-silence ratio)
            decimal result = (decimal)msPerWholeNote * noteFraction * modifierFactor * articulationFactor;
            // Should be at least 1 ms
            return Math.Max(1, (int)Math.Round(result, MidpointRounding.AwayFromZero));
        }
	Sizce bu durumda programımın kodundaki hesaplama hataları hangi kısımlarda neden kaynaklanıyor olabilir?
Merak edenler için programımın GitHub sayfasının bağlantısı: NeoBleeper GitHub sayfası
			
				Son düzenleme: