- Offizieller Beitrag
Um mit Nim die BASS-Dll nutzen zu können, ist der Wrapper "Nimbass" von "genotrance" erforderlich (https://github.com/genotrance/nimbass).
Dort gibt es auch eine Anleitung zum installieren per Nimble.
Im Prinzip benötigt man aber nur die "bass.dll" und "bass.nim". Im ZIP-Archiv (Anhang) habe ich diese beiden Dateien in den Ordner "nimbass" kopiert.
Das Nim-Programm zum abspielen einer MP3-Datei sieht dann so aus:
import os
import nimbass/bass
discard BASS_Init(cint(-1), cast[DWORD](44100), cast[DWORD](0), cast[DWORD](0), nil)
discard BASS_SetVolume(0.9)
var
iActive: DWORD
iLen: QWORD
iSeconds, iSecondsNow: cdouble
let sMp3File = "Albert Hammond - The Free Electric Band.mp3"
let cMp3File: cstring = sMp3File
let hChannel = BASS_StreamCreateFile(false, cMp3File, 0, 0, BASS_STREAM_PRESCAN or BASS_STREAM_AUTOFREE)
discard BASS_ChannelPlay(hChannel, false)
iLen = BASS_ChannelGetLength(hChannel, BASS_POS_BYTE)
iSeconds = BASS_ChannelBytes2Seconds(hChannel, iLen)
while true:
iActive = BASS_ChannelIsActive(hChannel)
if iActive != BASS_ACTIVE_PLAYING: break
iLen = BASS_ChannelGetPosition(hChannel, BASS_POS_BYTE)
iSecondsNow = BASS_ChannelBytes2Seconds(hChannel, iLen)
echo "Play: " & $int(iSecondsNow) & " / " & $int(iSeconds)
sleep(1000)
discard BASS_ChannelStop(hChannel)
discard BASS_Free()
Alles anzeigen
BASS_StreamCreateFile erwartet einen Pointer auf den Dateinamen, weshalb man den String erst in einen C-String (Char-Array) umwandeln muss.
Da ich mich mit Nim erst seit ein paar Tagen beschäftige, war da ziemlich viel "trial and error" nötig, aber so funktioniert es zumindest.
Edit: Hier noch eine überarbeitete Version. Die benutzt noch ein paar mehr Funktionen der BASS-dll und ist kommentiert:
import os
import strformat
import nimbass/bass
# Audiogeraet initialisieren
discard BASS_Init(cint(-1), cast[DWORD](44100), cast[DWORD](0), cast[DWORD](0), nil)
# Gesamtlautstaerke aendern (0 - 1.0)
discard BASS_SetVolume(1.0)
# die BASS-dll ist in C geschrieben, deswegen die C-Variablen
var
iLen: QWORD
iSeconds, iSecondsNow: cdouble
fBitrate, fVolume: cfloat
# BASS_StreamCreateFile erwartet einen Pointer auf den Dateinamen, deswegen ein C-String (Char-Array)
let pMp3File: cstring = r"f:\neue MP3s\Bryan Adams - Summer Of 69.mp3"
# MP3-File als Stream in den Speicher laden (wird am Ende automatisch freigegeben)
let hChannel = BASS_StreamCreateFile(false, pMp3File, 0, 0, BASS_STREAM_PRESCAN or BASS_STREAM_AUTOFREE)
# Lautstaerke (0 - 1.0) fuer den Stream aendern
discard BASS_ChannelSetAttribute(hChannel, BASS_ATTRIB_VOL, 0.9)
# die durchschnittliche Bitrate auslesen (Pointer auf fBitrate)
if BASS_ChannelGetAttribute(hChannel, BASS_ATTRIB_BITRATE, fBitrate.addr()):
echo "Bitrate: " & $int(fBitrate) & " kBit/s"
# so kann man die Laufstaerke fuer den Stream wieder auslesen (Pointer auf fVolume)
if BASS_ChannelGetAttribute(hChannel, BASS_ATTRIB_VOL, fVolume.addr()):
echo "Volume: " & fmt"{fVolume:<2.1f}"
# die Laufzeit des Streams auslesen (in Bytes)
iLen = BASS_ChannelGetLength(hChannel, BASS_POS_BYTE)
echo "Laenge in Bytes: " & $iLen
# die Laufzeit in Sekunden umrechnen
iSeconds = BASS_ChannelBytes2Seconds(hChannel, iLen)
echo "Laenge in Sekunden: " & $int(iSeconds)
if BASS_ChannelPlay(hChannel, false):
while true:
case BASS_ChannelIsActive(hChannel) # liefert ein DWORD zurueck
of BASS_ACTIVE_PLAYING: # Player noch aktiv
iLen = BASS_ChannelGetPosition(hChannel, BASS_POS_BYTE)
iSecondsNow = BASS_ChannelBytes2Seconds(hChannel, iLen)
echo "Position: " & $int(iSecondsNow) & " / " & $int(iSeconds)
sleep(1000) # eine Sekunde warten
of BASS_ACTIVE_STOPPED: break # Player Stop
of BASS_ACTIVE_PAUSED: break # Player Pause
of BASS_ACTIVE_PAUSED_DEVICE: break # Device Pause
of BASS_ACTIVE_STALLED: break # Datenstrom unterbrochen
else: break # ansonsten die While-Schleife beenden
discard BASS_ChannelStop(hChannel)
discard BASS_Free()
Alles anzeigen