Hallo liebe Community,
ich möchte mit Hilfe der bass.dll Vinylplatten aufnehmen (Datenfromat PCM) und in ein Byte Array speichern. Soweit so gut, das klappt. Nun möchte ich dem User während und nach der Aufnahme eine WaveForm anzeigen (klappt auch), damit mein Programm, nachdem der User die Schnitte auf der Waveform markiert hat, die Aufnahme in die einzelnen Musiktitel "zerhacken" kann. Soweit bin ich noch nicht.
Problem ist, ich möchte während der Aufnahme eine vertikale Linie auf der Waveform zeichnen, die den Aufnahmefortschritt anzeigt und diesen auch als TimeSpan in einem Label ausgeben.
Desweiteren möchte ich nach der Aufnahme den User den Schnitt markieren lassen, indem er mit der Maus auf die entsprechende Stelle klickt. Da soll dann eine weitere Linie angezeigt werden (das hab ich auch schon, jetzt möchte ich bloss, dass mir in einem Label diese Position als TimeSpan ausgibt).
Im Grunde genommen eher ein mathematisches Problem. aber ich krieg es einfach seit vier Stunden nicht hin, wie man die Werte umrechnet...
Es ist ein WPF MVVM Projekt, ich poste das hier trotzdem in diesem Unterforum, weil das Problem an sich nichts MVVM-spezifisches ist, sondern wirklich eher eins mit der bass.dll Ich versuche das mal so darzustellen, dass auch die Kollegen die mit WinForms unterwegs sind, das auch lesen können.
Ich habe folgende Properties:
Spoiler anzeigen
Und diese Funktionen:
Spoiler anzeigen
Bei der ersten Funktion bin ich mir unsicher ob das so richtig ist, denn wenn ich die maximale Aufnahmedauer auf 1 min setze, zeigt er mir, wenn ich mit der Maus ganz rechts auf die Waveform fahre, eben nicht genau eine Minute an... sondern "
Bei der zweiten Funktion bleibt die Stellung der Linie auf
Es ist also wie gesagt eher ein mathematisches Problem. Kann mir da jemand weiterhelfen?
ich möchte mit Hilfe der bass.dll Vinylplatten aufnehmen (Datenfromat PCM) und in ein Byte Array speichern. Soweit so gut, das klappt. Nun möchte ich dem User während und nach der Aufnahme eine WaveForm anzeigen (klappt auch), damit mein Programm, nachdem der User die Schnitte auf der Waveform markiert hat, die Aufnahme in die einzelnen Musiktitel "zerhacken" kann. Soweit bin ich noch nicht.
Problem ist, ich möchte während der Aufnahme eine vertikale Linie auf der Waveform zeichnen, die den Aufnahmefortschritt anzeigt und diesen auch als TimeSpan in einem Label ausgeben.
Desweiteren möchte ich nach der Aufnahme den User den Schnitt markieren lassen, indem er mit der Maus auf die entsprechende Stelle klickt. Da soll dann eine weitere Linie angezeigt werden (das hab ich auch schon, jetzt möchte ich bloss, dass mir in einem Label diese Position als TimeSpan ausgibt).
Im Grunde genommen eher ein mathematisches Problem. aber ich krieg es einfach seit vier Stunden nicht hin, wie man die Werte umrechnet...
Es ist ein WPF MVVM Projekt, ich poste das hier trotzdem in diesem Unterforum, weil das Problem an sich nichts MVVM-spezifisches ist, sondern wirklich eher eins mit der bass.dll Ich versuche das mal so darzustellen, dass auch die Kollegen die mit WinForms unterwegs sind, das auch lesen können.
Ich habe folgende Properties:
VB.NET-Quellcode
- Public Property WFBreite As Double 'Breite der WaveForm
- Private ReadOnly Property MaxTrackLaengeInBytes As Double 'Die begrenzte maximale Aufnahmedauer
- Get
- If LaengeInBytes Then 'Der User kann diese entweder in Megabyte eingeben oder in Minuten, gewaehlt durch LaengeInBytes As Boolean
- Return CDbl(MaxMB) * 1024 * 1024 'MaxMB: eingegebener Wert für maximale MegaBytes; Umrechnung von Megabytes in Bytes
- Else
- Return 44100 * 16 * 2 * CDbl(MaxMinutes) * 60 / 8 'MaxMinutes: eingegebener maximaler Wert für Minuten, Umrechnung in Bytes für PCM-Format (Samplerate * Bittiefe * 2 Kanäle (stereo) * MaxMinutes * 60 Sekunden / 8
- End If
- End Get
- End Property
- Public Property RecordingXPosWF As Double 'X-Position der vertikalen Linie für den Aufnahmefortschritt
- Private _MovingXPosWF As Double ''X-Position der vertikalen Linie, die mit einem Klick festgelegt wird
- Public Property MovingXPosWF As Double
- Get
- Return _MovingXPosWF
- End Get
- Set(value As Double)
- _MovingXPosWF = value
- AktuellePosition = TimeSpan.FromSeconds(GetPositionInSeconds(value))
- RaisePropertyChanged() 'MVVM-spezifisch
- End Set
- End Property
- Public Property AktuellePosition As TimeSpan 'diese wird auf einem Label ausgegeben; aktuelle Position der Maus auf der Waveform als TimeSpan
Und diese Funktionen:
VB.NET-Quellcode
- Private Function GetPositionInSeconds(CursorPos As Double) As Double 'Umrechnen der Mausposition auf der Waveform in Sekunden, da bin ich mir unsicher ob das so die richtigen Werte gibt.
- Dim AufnahmeLaenge As Double = Bass.BASS_ChannelBytes2Seconds(RecordingChannel, Bass.BASS_ChannelGetLength(RecordingChannel, BASSMode.BASS_POS_BYTE))
- Dim Visualisierungbreite = Bass.BASS_ChannelGetPosition(RecordingChannel, BASSMode.BASS_POS_BYTE) * MaxTrackLaengeInBytes / WFBreite ' da die Aufnahme nicht jedes Mal die maximal festgelegte Länge hat, berechne ich hier die visuelle Breite der tatsächlich aufgenommenen Daten nach Beenden der Aufnahme, hier könnte der Fehler liegen
- Dim percent As Double = CursorPos / Visualisierungbreite * 100
- Return AufnahmeLaenge / 100 * percent
- End Function
- Private Function MyRecording(handle As Integer, buffer As IntPtr, length As Integer, user As IntPtr) As Boolean ' Callback-Funktion, wird während der Aufnahme aufgerufen
- If length > 0 AndAlso buffer <> IntPtr.Zero Then
- If RecordedData Is Nothing OrElse RecordedData.Length < length Then
- RecordedData = New Byte(length) {}
- End If
- ' copy from managed to unmanaged memory
- Marshal.Copy(buffer, RecordedData, 0, length)
- BytesWritten += length
- Dim AufnahmeLaenge As Double = Bass.BASS_ChannelBytes2Seconds(RecordingChannel, Bass.BASS_ChannelGetLength(RecordingChannel, BASSMode.BASS_POS_BYTE)) 'diese vier Zeilen hier müssen die Aufnahmeposition von Bytes (Aufnahmeposition) in Pixel (bzw. Units bei WPF) (Position der Linie auf der Waveform) umgerechnet werden, das klappt nicht, die Linie bleibt auf Position 0.
- Dim Visualisierungsbreite = Bass.BASS_ChannelGetPosition(RecordingChannel, BASSMode.BASS_POS_BYTE) * MaxTrackLaengeInBytes / WFBreite
- Dim percent As Double = Bass.BASS_ChannelGetPosition(RecordingChannel, BASSMode.BASS_POS_BYTE) / Visualisierungbreite * 100
- RecordingXPosWF = 60 / 100 * percent
- ' get and draw our live recording waveform
- WF.RenderRecording(buffer, length)
- Services.ServiceContainer.GetService(Of IMainWindowService)?.HoleDispatcher().Invoke(Sub() WellenFormZeichnen())
- End If
- Return True
- End Function
Bei der ersten Funktion bin ich mir unsicher ob das so richtig ist, denn wenn ich die maximale Aufnahmedauer auf 1 min setze, zeigt er mir, wenn ich mit der Maus ganz rechts auf die Waveform fahre, eben nicht genau eine Minute an... sondern "
00:00:00.5320000
".Bei der zweiten Funktion bleibt die Stellung der Linie auf
0
.Es ist also wie gesagt eher ein mathematisches Problem. Kann mir da jemand weiterhelfen?