aicher1998
Goto Top

VB.Net oder C-Sharp Musik Beats erkennen

Hallo

Ich soll für eine Party einen RGB LED Strip an die Musik anpassen können.

Inzwischen hab ich etwas gefunden, sodass ich es über die Lautstärke machen kann (Pegel über 60% bewirkt eine Farbänderung), das ist aber sehr ungenau.

Ich suche nun seit 2 Tagen und finde nichts außer C++ Programmcode der auf eine DLL names fmodex.dll zugreift.
Leider lässt sich diese DLL nicht bei VB hinzufügen und leider sind meine C++ Kenntnisse nicht ausreichend.
Das hab ich hier gefunden.

Ich wäre auch sehr dankbar, wenn mir jemand eine kostenlose DLL (oder vergleichbares) aufzeigen kann, mit der ich Beats erkennen kann, um so das Licht an die Musik angepasst schalten zu können.
Perfekt wäre, wenn ich dazu keine Audio-Datei auswählen müsste, sondern direkt über die Soundkarte arbeiten kann.

Gruß
Aicher

Content-ID: 306961

Url: https://administrator.de/contentid/306961

Ausgedruckt am: 22.11.2024 um 00:11 Uhr

129413
129413 13.06.2016 aktualisiert um 00:10:20 Uhr
Goto Top
Diesen c# Code kannst du sehr leicht entweder in VB.NET umwandeln oder als DLL kompilieren und in deinem Projekt verwenden:
http://codereview.stackexchange.com/questions/78589/beat-detection-algo ...

Stichwort zum Thema lautet Fast Fourier Transformation.
Aber ich gehe mal wieder davon aus das dich der Background nicht juckt, "Schulschwänzer" face-big-smile

Gruß Skybird
Aicher1998
Aicher1998 13.06.2016 aktualisiert um 00:15:05 Uhr
Goto Top
Zitat von @129413:

Diesen c# Code kannst du sehr leicht entweder in VB.NET umwandeln oder als DLL kompilieren und in deinem Projekt verwenden:
http://codereview.stackexchange.com/questions/78589/beat-detection-algo ...
Wow thanks, schaut vielversprechend aus!
Werd mich dann mal an die Programm-Arbeit machen...

Stichwort zum Thema lautet Fast Fourier Transformation.
Aber ich gehe mal wieder davon aus das dich der Background nicht juckt, "Schulschwänzer" face-big-smile
Ich bin sehr interessiert in mathematische Formeln und deren Herangehensweise aber ich hatte leider kein Gymnasium-Mathe =D Dadurch ist mir FFT zu hoch - würde es aber gerne besser verstehen können face-smile

Wie kann das sein, dass man zu dem Thema Beats erkennen so wenig in VB findet (fast immer nur C oder C++ oder PHP) ?
129413
129413 13.06.2016 aktualisiert um 00:19:53 Uhr
Goto Top
VB ist am Ende. Hat MS die letzten Monate auch schon verlauten lassen.

Ich würde an deiner Stelle auf c# umsteigen, der Umstieg ist von VB.Net nicht so schwer wie man vielleicht denkt. Wenn man die typischen Programmiertechniken beherrscht ist das nur wie Vokabeln lernen.

Der Bereich ist auch eher etwas für Profis, und die geben sich mit VB.net schon lange nicht mehr ab, das ist der Grund warum du dazu sehr wenig in VB dazu findest.
Aicher1998
Aicher1998 13.06.2016 um 12:04:38 Uhr
Goto Top
Zitat von @129413:

Diesen c# Code kannst du sehr leicht entweder in VB.NET umwandeln oder als DLL kompilieren und in deinem Projekt verwenden:
http://codereview.stackexchange.com/questions/78589/beat-detection-algo ...
So, hab das ganze mal umgeschrieben. LoaderLock musste ich noch deaktivieren.
Aber jetzt bekomme ich beim Initialisieren von WASAPI
            result = BASS_WASAPI_Init(_DeviceCode, 0, 0, BASSWASAPIInit.BASS_WASAPI_BUFFER, 1.0F, 0.05F, _WasapiProcess, IntPtr.Zero)
Den Fehler hier
unable

Wieso ist das so?

VB ist am Ende. Hat MS die letzten Monate auch schon verlauten lassen.
Hab nix mitbekommen. Wenn VB, C#, F# ... alle auf dem selben Framework basieren, wie kann das eine dann schlechter sein als das andere?
Ich würde an deiner Stelle auf c# umsteigen, der Umstieg ist von VB.Net nicht so schwer wie man vielleicht denkt. Wenn man die typischen Programmiertechniken beherrscht ist das nur wie Vokabeln lernen.
Ich kann mich nicht mal von der 2010er trenne und auf 2012 umsteigen face-sad
Ich liebe VB.net 2010 face-smile

Der Bereich ist auch eher etwas für Profis, und die geben sich mit VB.net schon lange nicht mehr ab, das ist der Grund warum du dazu sehr wenig in VB dazu findest.
Es wird doch wohl eine einfache DLL zu geben?
129413
129413 13.06.2016 aktualisiert um 12:12:57 Uhr
Goto Top
Zitat von @Aicher1998:
Hab nix mitbekommen. Wenn VB, C#, F# ... alle auf dem selben Framework basieren, wie kann das eine dann schlechter sein als das andere?
Es ist VB.Net an sich, die Sprache ist an einem Limit angekommen was Erweiterbarkeit angeht.
Funktional werden nur noch die anderen Sprachen von Neuerungen profitieren.
Sicher basieren alle auf der CLR, aber die Profis lieben halt andere Sprachen und deswegen findest du ab einem gewissen Level keinen Code mehr für VB, da sich c# c++ und Co. besser für solche Aufgaben eignen und es den Code nicht so aufbläht wie bei VB.
Wurde auf der letzte Developer Konferenz veröffentlicht. Suche noch den Link.
Ich kann mich nicht mal von der 2010er trenne und auf 2012 umsteigen face-sad
Lernen müssen wir unser Leben lang.
Ich liebe VB.net 2010 face-smile
Ich liebe meine Transalp, aber fahre ich sie deswegen mein Leben lang face-wink
Es wird doch wohl eine einfache DLL zu geben?
Du willst doch das Rad neu erfinden hast du erst neulich groß posaunt face-wink
Aicher1998
Aicher1998 13.06.2016 um 12:23:03 Uhr
Goto Top
Zitat von @129413:

Zitat von @Aicher1998:
Hab nix mitbekommen. Wenn VB, C#, F# ... alle auf dem selben Framework basieren, wie kann das eine dann schlechter sein als das andere?
Es ist VB.Net an sich, die Sprache ist an einem Limit angekommen was Erweiterbarkeit angeht.
Häh? Neue DLLs schreiben ist doch nicht so schwer (für Microsoft) ?
Funktional werden nur noch die anderen Sprachen von Neuerungen profitieren.
Wenn C# weiterentwickelt wird, dann wird ja auch VB weiter entwickelt (gleiche CLR)...
Sicher basieren alle auf der CLR, aber die Profis lieben halt andere Sprachen und deswegen findest du ab einem gewissen Level keinen Code mehr für VB, da sich c# c++ und Co. besser für solche Aufgaben eignen und es den Code nicht so aufbläht wie bei VB.
Also ist der größte Unterschied die Anzahl der Codezeilen?
Ich kann mich nicht mal von der 2010er trenne und auf 2012 umsteigen face-sad
Lernen müssen wir unser Leben lang.
Joa, wenigstens mal ein guter Grund umzusteigen. Ob ich jetzt aus Eigeninitiative umsteige oder später aus beruflichen Gründen, ist egal. Bzw es ist besser wenn ich früher umsteige, dann mach ich das mal face-smile
C++ lern ich schon aber nur für den Arduino
Aber ich glaub ich mach dann erst mal C#...
Ich liebe VB.net 2010 face-smile
Ich liebe meine Transalp, aber fahre ich sie deswegen mein Leben lang face-wink
Wenn du glück hast...
Es wird doch wohl eine einfache DLL zu geben?
Du willst doch das Rad neu erfinden hast du erst neulich groß posaunt face-wink
Das war bei etwas anderem weil ich eine Herausforderung gesucht habe.

Ich muss zugeben, einen gewisen Reiz hat es natürlich C# zu lernen, da Syntax einfach PHP, C++, Java und co sehr ähnlich ist.
Aber die C# IDE stört mich stark!
129413
129413 13.06.2016 aktualisiert um 12:30:30 Uhr
Goto Top
Zitat von @Aicher1998:
Wenn C# weiterentwickelt wird, dann wird ja auch VB weiter entwickelt (gleiche CLR)...
Es geht nicht um die CLR sondern um die eigentlichen Sprach-Konstrukte nicht den Compiler im Background.
Also ist der größte Unterschied die Anzahl der Codezeilen?
Programmier sind faul face-smile und bei VB.Net schreibst du echt monströs viel im Vergleich zu anderen Sprachen.
Zum Anfangen ist es hilfreich wenn die Programmiersprache "spricht", das ändert sich aber mit der Zeit wenn man mal länger programmiert, das wirst du auch noch spüren.
Aber die C# IDE stört mich stark!
Welche sich doch problemlos anpassen lässt, noch besser ab VS2015

Jedem das seine. face-smile
Aicher1998
Aicher1998 13.06.2016 um 13:10:36 Uhr
Goto Top
Zitat von @129413:

Zitat von @Aicher1998:
Wenn C# weiterentwickelt wird, dann wird ja auch VB weiter entwickelt (gleiche CLR)...
Es geht nicht um die CLR sondern um die eigentlichen Sprach-Konstrukte nicht den Compiler im Background.
Sorry versteh ich nicht ganz...
Also ist der größte Unterschied die Anzahl der Codezeilen?
Programmier sind faul face-smile und bei VB.Net schreibst du echt monströs viel im Vergleich zu anderen Sprachen.
Sowas zum Beispiel?
My.Computer.FileSystem.WriteAllText
face-smile
Zum Anfangen ist es hilfreich wenn die Programmiersprache "spricht", das ändert sich aber mit der Zeit wenn man mal länger programmiert, das wirst du auch noch spüren.
Kann man dennoch VB als Einstiegssprache empfehlen, obwohl die Syntax im Vergleich zu anderen Sprachen vollkommen anders ist? Ein Freund will VB lernen (von mir)...

Aber die C# IDE ist doch anders aufgebaut als die von VB oder?

Also kann man folgendes sagen?
  • VB und C# können genau dasselbe
  • Die Klassennamen, Namespaces, Datentypen, ... sind alles dieselben
  • Nur die Syntax ist anders
Passt das so?
129413
129413 13.06.2016 aktualisiert um 14:12:16 Uhr
Goto Top
Zitat von @Aicher1998:
Zitat von @Aicher1998:
Wenn C# weiterentwickelt wird, dann wird ja auch VB weiter entwickelt (gleiche CLR)...
Es geht nicht um die CLR sondern um die eigentlichen Sprach-Konstrukte nicht den Compiler im Background.
Sorry versteh ich nicht ganz...
Die eigentlichen syntaktischen Sprachunterschiede wie Closures etc. pp.
Also ist der größte Unterschied die Anzahl der Codezeilen?
Programmier sind faul face-smile und bei VB.Net schreibst du echt monströs viel im Vergleich zu anderen Sprachen.
Sowas zum Beispiel?
My.Computer.FileSystem.WriteAllText
face-smile
Jepp.
Zum Anfangen ist es hilfreich wenn die Programmiersprache "spricht", das ändert sich aber mit der Zeit wenn man mal länger programmiert, das wirst du auch noch spüren.
Kann man dennoch VB als Einstiegssprache empfehlen, obwohl die Syntax im Vergleich zu anderen Sprachen vollkommen anders ist? Ein Freund will VB lernen (von mir)...
Für Ersteinsteiger ist es auf jeden Fall eine Erleichterung die gängigen Sprachkonstrukte kennen zu lernen.
Aber die C# IDE ist doch anders aufgebaut als die von VB oder?
Was soll da am Editor großartig anders sein ?? Für mich nicht großartig viel Unterschied ...
Also kann man folgendes sagen?
  • VB und C# können genau dasselbe
  • Die Klassennamen, Namespaces, Datentypen, ... sind alles dieselben
  • Nur die Syntax ist anders
Passt das so?
Liest du ausführlich hier nach, bevor ich jetzt weit aushole:
Comparison of C Sharp and Visual Basic .NET

C# hat einfach eine größere Community, obwohl es für beide Sprachen Konverter gibt die in die andere Sprache übersetzen, ist c# einfach weiter verbreitet, auch weil es anderen Sprachen wie Java und C ähnlicher ist.
Aicher1998
Aicher1998 13.06.2016 um 14:52:02 Uhr
Goto Top
Zitat von @129413:
C# hat einfach eine größere Community, obwohl es für beide Sprachen Konverter gibt die in die andere Sprache übersetzen, ist c# einfach weiter verbreitet,
Ok überzeugt face-smile
auch weil es anderen Sprachen wie Java und C ähnlicher ist.
Sagt ich auch schon face-smile

Dann schau ich mir jetzt erst mal das 2010er genauer an (da hab ich den Installer glaub ich noch irgendwo) und dann hol ich mir das 2015er.
hier heißt es, es dürfe nicht kommerziell verwendet werden??
Aicher1998
Aicher1998 13.06.2016 um 14:53:15 Uhr
Goto Top
Meine eigentliche Frage face-smile

Zitat von @Aicher1998:

Zitat von @129413:

Diesen c# Code kannst du sehr leicht entweder in VB.NET umwandeln oder als DLL kompilieren und in deinem Projekt verwenden:
http://codereview.stackexchange.com/questions/78589/beat-detection-algo ...
So, hab das ganze mal umgeschrieben. LoaderLock musste ich noch deaktivieren.
Aber jetzt bekomme ich beim Initialisieren von WASAPI
>             result = BASS_WASAPI_Init(_DeviceCode, 0, 0, BASSWASAPIInit.BASS_WASAPI_BUFFER, 1.0F, 0.05F, _WasapiProcess, IntPtr.Zero)
> 
Den Fehler hier
unable

Wieso ist das so?
Aicher1998
Aicher1998 14.06.2016 um 00:25:36 Uhr
Goto Top
Zitat von @129413:

Diesen c# Code kannst du sehr leicht entweder in VB.NET umwandeln oder als DLL kompilieren und in deinem Projekt verwenden:
http://codereview.stackexchange.com/questions/78589/beat-detection-algo ...

Danke noch mal. Ich hab den Code jetzt nicht noch mal übersetzt, sondern mir einfach die C# IDE installiert.

Mein Problem ist jetzt dass die Variable int level aus der Funktion PerformAnalysis immer 0 bekommt.
Ich versteh nicht wieso ? face-sad

using System;
using System.Threading;
using System.Windows.Forms;
using Un4seen.Bass;
using Un4seen.BassWasapi;

using System.Runtime.InteropServices;

namespace BeatDetect {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        public Szab.BeatDetector.SpectrumBeatDetector.BeatDetectedHandler BDH = new Szab.BeatDetector.SpectrumBeatDetector.BeatDetectedHandler(TE);
        public Szab.BeatDetector.SpectrumBeatDetector x = new Szab.BeatDetector.SpectrumBeatDetector (0);

     private void button2_Click(object sender, EventArgs e){
            x.Subscribe(BDH);
            x.StartAnalysis();
            x.SetBassSensivity(Szab.BeatDetector.SensivityLevel.VERY_LOW);
        }

      public static void TE(byte a) {
            MessageBox.Show("");  
        }

   
    }
}



namespace Szab.BeatDetector {
    public enum SensivityLevel {
        VERY_LOW = 120,
        LOW = 110,
        NORMAL = 100,
        HIGH = 80,
        VERY_HIGH = 70
    };

    public sealed class SpectrumBeatDetector {
        #region Fields
        // Constants
        private const int BANDS = 10;
        private const int HISTORY = 50;

        // Events
        public delegate void BeatDetectedHandler(byte Value);
        private event BeatDetectedHandler OnDetected;

        // Threading
        private Thread _AnalysisThread;

        // BASS Process
        private WASAPIPROC _WasapiProcess = new WASAPIPROC(SpectrumBeatDetector.Process);

        // Analysis settings
        private int _SamplingRate;
        private int _DeviceCode;
        private SensivityLevel _BASSSensivity;
        private SensivityLevel _MIDSSensivity;

        // Analysis data
        private float _FFTData = new float[4096];
        private double[,] _History = new double[BANDS, HISTORY];

        #endregion

        #region Setup methods
        public SpectrumBeatDetector(int DeviceCode, int SamplingRate = 44100, SensivityLevel BASSSensivity = SensivityLevel.NORMAL, SensivityLevel MIDSSensivity = SensivityLevel.NORMAL) {
            _SamplingRate = SamplingRate;
            _BASSSensivity = BASSSensivity;
            _MIDSSensivity = MIDSSensivity;
            _DeviceCode = DeviceCode;

            Init();
        }

        // BASS initialization method
        private void Init() {
            bool result = false;

            // Initialize BASS on default device
            result = Bass.BASS_Init(0, _SamplingRate, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);

            if (!result) {
                throw new Exception ();
                // throw new BassInitException(Bass.BASS_ErrorGetCode().ToString());
            }

            // Initialize WASAPI
            result = BassWasapi.BASS_WASAPI_Init(_DeviceCode, 0, 0, BASSWASAPIInit.BASS_WASAPI_BUFFER, 1f, 0.05f, _WasapiProcess, IntPtr.Zero);

            if (!result) {
                throw new Exception() ;
                // throw new BassWasapiInitException(Bass.BASS_ErrorGetCode().ToString());
            }

            BassWasapi.BASS_WASAPI_Start();
            System.Threading.Thread.Sleep(500);
        }


        ~SpectrumBeatDetector() {
            // Kill working thread and clean after BASS
            if (_AnalysisThread != null && _AnalysisThread.IsAlive) {
                _AnalysisThread.Abort();
            }

            Free();
        }

        // Sensivity Setters
        public void SetBassSensivity(SensivityLevel Sensivity) {
            _BASSSensivity = Sensivity;
        }

        public void SetMidsSensivity(SensivityLevel Sensivity) {
            _MIDSSensivity = Sensivity;
        }

        #endregion

        #region BASS-dedicated Methods
        // WASAPI callback, required for continuous recording
        private static int Process(IntPtr buffer, int length, IntPtr user) {
            return length;
        }

        // Cleans after BASS
        public void Free() {
            BassWasapi.BASS_WASAPI_Free();
            Bass.BASS_Free();
        }
        #endregion

        #region Analysis public methods
        // Starts a new Analysis Thread
        public void StartAnalysis() {
            // Kills currently running analysis thread if alive
            if (_AnalysisThread != null && _AnalysisThread.IsAlive) {
                _AnalysisThread.Abort();
            }

            // Starts a new high-priority thread
            _AnalysisThread = new Thread(delegate () {
                while (true)  {
                    //Stopwatch SW = new Stopwatch();
                    //SW.Start();
                    Thread.Sleep(5);
                    PerformAnalysis();
                    //SW.Stop();
                    //Console.WriteLine(SW.Elapsed);
                }
            });

            _AnalysisThread.Priority = ThreadPriority.Highest;
            _AnalysisThread.Start();
        }

        // Kills running thread
        public void StopAnalysis()
        {
            if (_AnalysisThread != null && _AnalysisThread.IsAlive)
            {
                _AnalysisThread.Abort();
            }
        }
        #endregion

        #region Event handling
        public void Subscribe(BeatDetectedHandler Delegate) {
            OnDetected += Delegate;
        }

        public void UnSubscribe(BeatDetectedHandler Delegate) {
            OnDetected -= Delegate;
        }
        #endregion

        #region Analysis private methods
        // Shifts history n places to the right
        private void ShiftHistory(int n) {
            for (int i = 0; i < BANDS; i++) {
                for (int j = HISTORY - 1 - n; j >= 0; j--) {
                    _History[i, j + n] = _History[i, j];
                }
            }
        }

        // Performs FFT analysis in order to detect beat
        private void PerformAnalysis() {
            // Specifes on which result end which band (dividing it into 10 bands)
            // 19 - bass, 187 - mids, rest is highs
            int BandRange = { 4, 8, 18, 38, 48, 94, 140, 186, 466, 1022, 22000 };
            double BandsTemp = new double[BANDS];
            int n = 0;
            int level = BassWasapi.BASS_WASAPI_GetLevel();

            // Get FFT
            int ret = BassWasapi.BASS_WASAPI_GetData(_FFTData, (int)BASSData.BASS_DATA_FFT1024 | (int)BASSData.BASS_DATA_FFT_COMPLEX); //get channel fft data
            if (ret < -1) return;

            // Calculate the energy of every result and divide it into subbands
            float sum = 0;

            for (int i = 2; i < 2048; i = i + 2) {
                float real = _FFTData[i];
                float complex = _FFTData[i + 1];
                sum += (float)Math.Sqrt((double)(real * real + complex * complex));

                if (i == BandRange[n]) {
                    BandsTemp[n++] = (BANDS * sum) / 1024;
                    sum = 0;
                }
            }

            // Detect beat basing on FFT results
            DetectBeat(BandsTemp, level);

            // Shift the history register and save new values
            ShiftHistory(1);

            for (int i = 0; i < BANDS; i++) {
                _History[i, 0] = BandsTemp[i];
            }
        }

        // Calculate the average value of every band
        private double CalculateAverages() {
            double avg = new double[BANDS];

            for (int i = 0; i < BANDS; i++) {
                double sum = 0;

                for (int j = 0; j < HISTORY; j++) {
                    sum += _History[i, j];
                }

                avg[i] = (sum / HISTORY);
            }

            return avg;
        }

        // Detects beat basing on analysis result
        // Beat detection is marked on the first three bits of the returned value
        private byte DetectBeat(double Energies, int volume) {
            // Sound height ranges (1, 2 is bass, next 6 is mids)
            int Bass = 3;
            int Mids = 6;

            double avg = CalculateAverages();
            byte result = 0;
            double volumelevel = (double)volume / 32768 * 100;   // Volume level in %

            for (int i = 0; i < BANDS && result == 0; i++) {
                double C = 0;

                if (i < Bass) { C = 2.3 * ((double)_BASSSensivity / 100);}
                else if (i < Mids) {C = 2.89 * ((double)_MIDSSensivity / 100);}
                else {C = 3 * ((double)_MIDSSensivity / 100);}

                // Compare energies in all bands with C*average 
                if (Energies[i] > (C * avg[i]) && volumelevel > 1)  {// Second rule is for noise reduction
                    byte res = 0;
                    if (i < Bass) {res = 1;}
                    else if (i < Mids) {res = 2;}
                    else {res = 4;
                    }
                    result = (byte)(result | res);
                }
            }

            if (result > 0) {
                OnDetected(result);
            }

            return result;
        }
        #endregion

    }
}