Wave Dateien in SQLite Datenbank

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
rowo
Beiträge: 13
Registriert: 28.12.2017 17:45
Computerausstattung: Macbook Pro, Mid 2010
Lenovo Workstation, i5 3,2 Ghz, 32 GB RAM, 480 GB SSD, Nvidia Quadro
Wohnort: Bayern, nähe Augsburg

Wave Dateien in SQLite Datenbank

Beitrag von rowo »

Hallo liebe Purebasic Programmierer. Ich bin vor einiger Zeit auf Purebasic gestoßen und würde mich mittlerweile nicht mehr ganz als blutiger Anfänger bezeichnen. Aber aktuell beiße ich mir die Zähne an einer Sache aus. Ich habe hier rund 500 MB an WAV Dateien, über 800 ganz kurze Schnipsel von je 5-6 Sekunden. Die möchte ich in eine SQLite Datenbank packen und von da aufrufen und abspielen. Also nicht aus dem Dateisystem heraus z. B. C:\xxx\1.wav sondern als BLOB aus der Datenbank laden und dann abspielen lassen.
Ich habe mich in diese Anleitung eingearbeitet, nur gehts da um Bilder, die als BLOB gespeichert werden. http://forums.purebasic.com/german/view ... =9&t=24643
Irgendwie komme ich nicht weiter. Falls hier jemand eine Idee hat oder mir ein paar Tipps geben könnte...Vielen Dank.
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Wave Dateien in SQLite Datenbank

Beitrag von RSBasic »

Soweit ich weiß laut Erfahrungswerte von Leuten sollte man große Datenmenge nicht in die Datenbank auslagern, weil erstens die Datenbank sehr groß wird (was logisch ist) und zweitens weil die Performance der Datenbank sich verschlechtert. Ich meine, mal gelesen zu haben, dass man die Dateien lieber auf der Festplatte lassen soll, die in der Datenbank als Verweis eingetragen werden.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Wave Dateien in SQLite Datenbank

Beitrag von ccode_new »

Hallo rowo!

Hier einmal ein Beispiel:

Code: Alles auswählen

Procedure DateiHinzufuegen(aDatei.s)
  Protected *mem, size, sql.s, id_name.s, fstring
  If FileSize(aDatei) > 0 And FileSize(aDatei) < 8000000
    If ReadFile(0, aDatei)
      size = Lof(0)
      If size
        *mem = AllocateMemory(size)
        If *mem
          ReadData(0, *mem, size)
          SetDatabaseBlob(#DeineDB, 0, *mem, size)
          sql = "UPDATE tabelle SET "
          sql + "extdata = ? ,"
          sql + "extname = '" + GetFilePart(aDatei) + "' "
          sql + "WHERE name = '" + GetFilePart(aDatei) +"'"        
          If Not DatabaseUpdate(#DeineDB, sql) 
            Debug DatabaseError()
          Else
            MessageRequester("Hinweis", "Die Datei wurde der Datenbank hinzugefügt!", #PB_MessageRequester_Info)
          EndIf
          FreeMemory(*mem)
        EndIf
      EndIf
      CloseFile(0)
    EndIf
  ElseIf FileSize(aDatei) > 0 And FileSize(aDatei) > 8000000
    brechnung.d = FileSize(aDatei)/1000000
    MessageRequester("Fehler", "Die Datei darf 8 Mbyte nicht übersteigen."+Chr(13)+Chr(13)+"Ihre ausgewählte Datei ist "+StrD(brechnung)+" Mbyte groß.", #PB_MessageRequester_Error)
  ElseIf FileSize(aDatei) = -1
    MessageRequester("Fehler", "keine Datei ?", #PB_MessageRequester_Error)
  EndIf
EndIf
EndProcedure

Procedure DateiExtract(id_name.i, id_extFile.i, sel_name.s)
  Protected.s SQL, name, extname
  Protected *mem, size, fstring
  
  SQL = "SELECT * FROM tabelle"
  
  If DatabaseQuery(#DeineDB, SQL)
    While NextDatabaseRow(#DeineDB)   ; alle Einträge durchlaufen
      name = GetDatabaseString(#DeineDB, 1)
      If sel_name = name
        extname = GetDatabaseString(#DeineDB, id_name)
        
        saveFile$ = SaveFileRequester("Datei extrahieren", extname, "*.*", 0)
        
        size = DatabaseColumnSize(#DeineDB, id_extFile)
        
        If Not CheckDatabaseNull(#DeineDB, id_extFile)
          *mem = AllocateMemory(size)
          If *mem
            ; Mit GetDatabaseBlob laden wir nun die Daten in unseren Speicher.
            If GetDatabaseBlob(#DeineDB, id_extFile, *mem, size)
              If CreateFile(0, saveFile$)
                WriteData(0, *mem, size)    
                CloseFile(0)
                MessageRequester("Hinweis", "Die Datei wurde erfolgreich extrahiert.", #PB_MessageRequester_Info)
              Else
                Debug "Konnte die Datei nicht erstellen!"
                MessageRequester("Fehler", "Die Datei konnte nicht extrahiert werden.", #PB_MessageRequester_Error)
              EndIf               
              FreeMemory(*mem)
            EndIf
          EndIf
        EndIf
        Break
      EndIf
    Wend
    FinishDatabaseQuery(#DeineDB)
  EndIf
EndIf
EndProcedure
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
rowo
Beiträge: 13
Registriert: 28.12.2017 17:45
Computerausstattung: Macbook Pro, Mid 2010
Lenovo Workstation, i5 3,2 Ghz, 32 GB RAM, 480 GB SSD, Nvidia Quadro
Wohnort: Bayern, nähe Augsburg

Re: Wave Dateien in SQLite Datenbank

Beitrag von rowo »

Hallo. Die Datenbank wird sich nicht vergrößern und es werden keine neuen WAV Dateien hinzugefügt. Nur die vorhandenen sollen da rein und von da aufgerufen werden..
rowo
Beiträge: 13
Registriert: 28.12.2017 17:45
Computerausstattung: Macbook Pro, Mid 2010
Lenovo Workstation, i5 3,2 Ghz, 32 GB RAM, 480 GB SSD, Nvidia Quadro
Wohnort: Bayern, nähe Augsburg

Re: Wave Dateien in SQLite Datenbank

Beitrag von rowo »

Hallo, vielen Dank für die schnelle Antwort. Ich werde mir dein Beispiel gleich mal anschauen und vielleicht ist das die Lösung.

ccode_new hat geschrieben:Hallo rowo!

Hier einmal ein Beispiel:

Code: Alles auswählen

Procedure DateiHinzufuegen(aDatei.s)
  Protected *mem, size, sql.s, id_name.s, fstring
  If FileSize(aDatei) > 0 And FileSize(aDatei) < 8000000
    If ReadFile(0, aDatei)
      size = Lof(0)
      If size
        *mem = AllocateMemory(size)
        If *mem
          ReadData(0, *mem, size)
          SetDatabaseBlob(#DeineDB, 0, *mem, size)
          sql = "UPDATE tabelle SET "
          sql + "extdata = ? ,"
          sql + "extname = '" + GetFilePart(aDatei) + "' "
          sql + "WHERE name = '" + GetFilePart(aDatei) +"'"        
          If Not DatabaseUpdate(#DeineDB, sql) 
            Debug DatabaseError()
          Else
            MessageRequester("Hinweis", "Die Datei wurde der Datenbank hinzugefügt!", #PB_MessageRequester_Info)
          EndIf
          FreeMemory(*mem)
        EndIf
      EndIf
      CloseFile(0)
    EndIf
  ElseIf FileSize(aDatei) > 0 And FileSize(aDatei) > 8000000
    brechnung.d = FileSize(aDatei)/1000000
    MessageRequester("Fehler", "Die Datei darf 8 Mbyte nicht übersteigen."+Chr(13)+Chr(13)+"Ihre ausgewählte Datei ist "+StrD(brechnung)+" Mbyte groß.", #PB_MessageRequester_Error)
  ElseIf FileSize(aDatei) = -1
    MessageRequester("Fehler", "keine Datei ?", #PB_MessageRequester_Error)
  EndIf
EndIf
EndProcedure

Procedure DateiExtract(id_name.i, id_extFile.i, sel_name.s)
  Protected.s SQL, name, extname
  Protected *mem, size, fstring
  
  SQL = "SELECT * FROM tabelle"
  
  If DatabaseQuery(#DeineDB, SQL)
    While NextDatabaseRow(#DeineDB)   ; alle Einträge durchlaufen
      name = GetDatabaseString(#DeineDB, 1)
      If sel_name = name
        extname = GetDatabaseString(#DeineDB, id_name)
        
        saveFile$ = SaveFileRequester("Datei extrahieren", extname, "*.*", 0)
        
        size = DatabaseColumnSize(#DeineDB, id_extFile)
        
        If Not CheckDatabaseNull(#DeineDB, id_extFile)
          *mem = AllocateMemory(size)
          If *mem
            ; Mit GetDatabaseBlob laden wir nun die Daten in unseren Speicher.
            If GetDatabaseBlob(#DeineDB, id_extFile, *mem, size)
              If CreateFile(0, saveFile$)
                WriteData(0, *mem, size)    
                CloseFile(0)
                MessageRequester("Hinweis", "Die Datei wurde erfolgreich extrahiert.", #PB_MessageRequester_Info)
              Else
                Debug "Konnte die Datei nicht erstellen!"
                MessageRequester("Fehler", "Die Datei konnte nicht extrahiert werden.", #PB_MessageRequester_Error)
              EndIf               
              FreeMemory(*mem)
            EndIf
          EndIf
        EndIf
        Break
      EndIf
    Wend
    FinishDatabaseQuery(#DeineDB)
  EndIf
EndIf
EndProcedure
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Wave Dateien in SQLite Datenbank

Beitrag von Bisonte »

rowo hat geschrieben:Ich habe mich in diese Anleitung eingearbeitet, nur gehts da um Bilder, die als BLOB gespeichert werden. http://forums.purebasic.com/german/view ... =9&t=24643
Irgendwie komme ich nicht weiter. Falls hier jemand eine Idee hat oder mir ein paar Tipps geben könnte...Vielen Dank.
Hallo. Erstmal Top! Du hast das in meinen Augen beste Einstiegstutorial für SQLite gefunden ;)

Wenn dir die Sache mit den Blobs als Bildern absolut klar ist, dann sollte das mit WAV Dateien kein Problem darstellen.
Beides sind "nur" Binärdateien. Der einzige Unterschied : CatchImage wird durch CatchSound ersetzt. Das wars im Grunde schon.

Allerdings kann ich RSBasic nur zustimmen. Eine DB aus ca. 800 Dateien die gesamt eine Grösse von ca 500MB hat, ist schon hart
an der Grenze. Die Geschwindigkeit der DB wird extrem darunter leiden. Ausserdem ist es eine grosse Datei... die noch etwas grösser
wird, weil mit Sicherheit noch einiges dazugespeichert werden soll, und SQLite auch noch ein wenig Verwaltungsanhang besitzt.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
rowo
Beiträge: 13
Registriert: 28.12.2017 17:45
Computerausstattung: Macbook Pro, Mid 2010
Lenovo Workstation, i5 3,2 Ghz, 32 GB RAM, 480 GB SSD, Nvidia Quadro
Wohnort: Bayern, nähe Augsburg

Re: Wave Dateien in SQLite Datenbank

Beitrag von rowo »

Bisonte hat geschrieben:
rowo hat geschrieben:Ich habe mich in diese Anleitung eingearbeitet, nur gehts da um Bilder, die als BLOB gespeichert werden. http://forums.purebasic.com/german/view ... =9&t=24643
Irgendwie komme ich nicht weiter. Falls hier jemand eine Idee hat oder mir ein paar Tipps geben könnte...Vielen Dank.
Hallo. Erstmal Top! Du hast das in meinen Augen beste Einstiegstutorial für SQLite gefunden ;)

Wenn dir die Sache mit den Blobs als Bildern absolut klar ist, dann sollte das mit WAV Dateien kein Problem darstellen.
Beides sind "nur" Binärdateien. Der einzige Unterschied : CatchImage wird durch CatchSound ersetzt. Das wars im Grunde schon.

Allerdings kann ich RSBasic nur zustimmen. Eine DB aus ca. 800 Dateien die gesamt eine Grösse von ca 500MB hat, ist schon hart
an der Grenze. Die Geschwindigkeit der DB wird extrem darunter leiden. Ausserdem ist es eine grosse Datei... die noch etwas grösser
wird, weil mit Sicherheit noch einiges dazugespeichert werden soll, und SQLite auch noch ein wenig Verwaltungsanhang besitzt.
Hallo, danke für die schnelle Antwort. Die Waves bringe ich nun in die Datenbank. Allerdings bekomme ich beim Auslesen der Daten mit CatchSound den Fehler: ERROR Das angegebene #Sound ist nicht initialisiert. Hier mein Code... :roll:

Code: Alles auswählen

Procedure SpieleWav(id)
  If InitSound() = 0 
    MessageRequester("Fehler", "Fehler beim Initialisieren des Sounds!") 
    ProcedureReturn 
  EndIf 
  
  Protected size, *mem
  
  If DatabaseQuery(#DBAudio, "SELECT * FROM Waves WHERE Wid = " + Str(id))
    NextDatabaseRow(#DBAudio)
    
    size = DatabaseColumnSize(#DBAudio, AudioData)
    *mem = AllocateMemory(size)
    If *mem
      If GetDatabaseBlob(#DBAudio, AudioData, *mem, size)
        CatchSound(0, *mem)
        PlaySound (0)
      EndIf
      FreeMemory(*mem)
    EndIf
    FinishDatabaseQuery(#DBAudio)
  Else
    Debug DatabaseError()
  EndIf
  FreeSound(0)
EndProcedure
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Wave Dateien in SQLite Datenbank

Beitrag von ts-soft »

Ohne speichern und CatchSound geht es unter Windows ungefähr so:

Code: Alles auswählen

If GetDatabaseBlob(#DeineDB, id_extFile, *mem, size)
  PlaySound_(*mem, 0, #SND_MEMORY)
  FreeMemory(*mem)
EndIf
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Wave Dateien in SQLite Datenbank

Beitrag von Bisonte »

eine Abfrage nach "CatchSound()", ob der Sound initialisiert ist, wäre sinnvoll.

Code: Alles auswählen

; Wichtiger Bestandteil. Wenn fehlgeschlagen macht das Programm keinen weiteren Sinn ?
If InitSound() = 0 ; Sollte man möglichst nur einmal aufrufen...
  MessageRequester("Fehler", "Fehler beim Initialisieren des Sounds!")
  End
EndIf

Procedure SpieleWav(id)

  Protected size, *mem, Sound
  
  If DatabaseQuery(#DBAudio, "SELECT * FROM Waves WHERE Wid = " + Str(id))
    
    NextDatabaseRow(#DBAudio)
    
    size = DatabaseColumnSize(#DBAudio, AudioData)
    *mem = AllocateMemory(size)
    
    If *mem
      If GetDatabaseBlob(#DBAudio, AudioData, *mem, size)
        Sound = CatchSound(#PB_Any, *mem, size)
        If IsSound(Sound) ; Ist der Sound korrekt initialisiert ?
          PlaySound (Sound)          
        EndIf
      EndIf
      FreeMemory(*mem)
    EndIf
    FinishDatabaseQuery(#DBAudio)
  Else
    Debug DatabaseError()
  EndIf
  
  If IsSound(Sound) ; Ist der Sound korrekt initialisiert ?
    FreeSound(Sound)
  EndIf
  
EndProcedure 
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
rowo
Beiträge: 13
Registriert: 28.12.2017 17:45
Computerausstattung: Macbook Pro, Mid 2010
Lenovo Workstation, i5 3,2 Ghz, 32 GB RAM, 480 GB SSD, Nvidia Quadro
Wohnort: Bayern, nähe Augsburg

Re: Wave Dateien in SQLite Datenbank

Beitrag von rowo »

Hallo, dein Code funktioniert. Vielen Dank schon mal. Nur noch ein Problem: Wie kann ich da die Lautstärke ändern? Wenn ich SoundVolume nehme, bekomme ich einen Fehler.
ts-soft hat geschrieben:Ohne speichern und CatchSound geht es unter Windows ungefähr so:

Code: Alles auswählen

If GetDatabaseBlob(#DeineDB, id_extFile, *mem, size)
  PlaySound_(*mem, 0, #SND_MEMORY)
  FreeMemory(*mem)
EndIf
Antworten