#include "GSLDatei.h" #ifdef WIN32 #include "Sound.h" #else #include "Sound.h" #endif using namespace GSL; // Inhalt der GSLDatei Klasse aus GSLDatei.h // Konstruktor GSLDatei::GSLDatei() : ReferenceCounter() { sounds = new Array< SoundKopf >(); pfad = new Text(); } // Destruktor GSLDatei::~GSLDatei() { sounds->release(); pfad->release(); } // Datei open void GSLDatei::setDatei(Framework::Text* txt) { cs.lock(); pfad->setText(txt); cs.unlock(); } void GSLDatei::setDatei(const char* txt) { cs.lock(); pfad->setText(txt); cs.unlock(); } bool GSLDatei::leseDaten() { cs.lock(); sounds->leeren(); Datei d; d.setDatei(*pfad); if (!d.getSize()) { cs.unlock(); return 1; } if (!d.open(Datei::Style::lesen)) { cs.unlock(); return 0; } unsigned char sAnz = 0; d.lese((char*)&sAnz, 1); // Datei Sound - Köpfe einlesen for (int i = 0; i < sAnz; i++) { SoundKopf kpf; bool bit = 0; char len = 0; // Namenslänge lesen for (int i = 0; i < 4; i++) { d.getNextBit(bit); len = (char)(len | (((char)bit << (3 - i)) & (1 << (3 - i)))); } len &= 15; // Name lesen for (int i = 0; i < len; i++) { char zeichen = 0; for (int j = 0; j < 5; j++) { d.getNextBit(bit); zeichen = (char)(zeichen | (((char)bit << (4 - j)) & (1 << (4 - j)))); } zeichen &= 31; if (zeichen == 27) zeichen = 'ü'; if (zeichen == 28) zeichen = 'ö'; if (zeichen == 29) zeichen = 'ä'; if (zeichen == 30) zeichen = 'ß'; if (zeichen == 31) zeichen = '.'; if (zeichen < 27) zeichen = (char)(zeichen + 'a'); kpf.name.append(&zeichen, 1); } // Chanel Anzahl lesen d.getNextBit(bit); kpf.channels = (char)(bit + 1); // Sample Rate lesen d.lese((char*)&kpf.sampleRate, 4); // Position des Sounds in der Datei lesen d.lese((char*)&kpf.datPos, 8); // Länge des Sounds lesen int sLen = 0; d.lese((char*)&sLen, 4); kpf.datEnd = kpf.datPos + sLen; kpf.pfad = pfad->getText(); sounds->add(kpf); } d.close(); cs.unlock(); return 1; } int GSLDatei::getSoundAnzahl() { return sounds->getEintragAnzahl(); } Text* GSLDatei::getSoundName(int num) { if (!sounds->hat(num)) return 0; return new Text(sounds->get(num).name); } // Laden GSLSoundV* GSLDatei::getSound(Framework::Text* name) { GSLSoundV* ret = getSound(*name); name->release(); return ret; } GSLSoundV* GSLDatei::getSound(const char* name) { cs.lock(); int anz = sounds->getEintragAnzahl(); for (int i = 0; i < anz; i++) { if (sounds->get(i).name.istGleich(name)) { cs.unlock(); return new GSLSound(sounds->get(i)); } } cs.unlock(); return 0; } // Speichern bool GSLDatei::speicherSound(GSLSoundV* zSound, Framework::Text* name) { bool ret = speicherSound(zSound, *name); name->release(); return ret; } bool GSLDatei::speicherSound(GSLSoundV* zSound, const char* name) { Text kName; for (const char* c = name; *c; ++c) { if (*c >= 'A' && *c <= 'Z') kName.append((char)(*c + 32)); if (*c >= 'a' && *c <= 'z') kName.append(*c); if (*c == 'Ü' || *c == 'ü') kName.append('ü'); if (*c == 'Ö' || *c == 'ö') kName.append('ö'); if (*c == 'Ä' || *c == 'ä') kName.append('ä'); if (*c == 'ß') kName.append('ß'); if (*c == '.') kName.append('.'); if (kName.getLength() == 15) break; } name = kName; cs.lock(); // Prüfen ob bereits vorhanden int anz = sounds->getEintragAnzahl(); for (int i = 0; i < anz; i++) { if (sounds->get(i).name.istGleich(name)) { cs.unlock(); return 0; } } Text tmpPf = pfad->getText(); tmpPf += "_"; GetFreePfad(&tmpPf); Datei tmp; tmp.setDatei(tmpPf); tmp.erstellen(); if (!tmp.open(Datei::Style::schreiben)) { cs.unlock(); return 0; } char* buffer = new char[0x4000]; // Neuen Sound in Temporäre Datei schreiben zSound->open(); while (1) { int len = 0; if ((len = zSound->getDaten(buffer, 0x4000)) < 0) break; tmp.schreibe(buffer, len); } zSound->close(); delete[] buffer; tmp.close(); int hLen = 1; unsigned char sAnz = (unsigned char)sounds->getEintragAnzahl(); // Sound Kopf Länge errechnen for (int i = 0; i < sAnz; i++) { SoundKopf kpf = sounds->get(i); hLen += (140 + 5 * kpf.name.getLength()) / 8; } Datei alt; alt.setDatei(*pfad); // Sound Kopf Erstellen SoundKopf kpf; kpf.channels = (char)(!zSound->istMono() + 1); kpf.name = name; kpf.pfad = pfad->getText(); kpf.sampleRate = zSound->getSampleRate(); kpf.datPos = (alt.getSize() <= 0 ? 1 : alt.getSize()); kpf.datEnd = tmp.getSize() + kpf.datPos; sounds->add(kpf); Text neuPf = pfad->getText(); neuPf += "_"; GetFreePfad(&neuPf); Datei neu; neu.setDatei(neuPf); neu.erstellen(); if (!neu.open(Datei::Style::schreiben)) { sounds->remove(sAnz); tmp.remove(); cs.unlock(); return 0; } sAnz = (unsigned char)sounds->getEintragAnzahl(); neu.schreibe((char*)&sAnz, 1); // Sound Köpfe speichern for (int i = 0; i < sAnz; i++) { SoundKopf k = sounds->get(i); k.datPos += (140 + 5 * kpf.name.getLength()) / 8; k.datEnd += (140 + 5 * kpf.name.getLength()) / 8; int l = k.name.getLength(); // Namenslänge speichern neu.setNextBit((l & 8) != 0); neu.setNextBit((l & 4) != 0); neu.setNextBit((l & 2) != 0); neu.setNextBit((l & 1) != 0); for (int j = 0; j < l; j++) { // Name speichern char c = k.name.getText()[j]; if (c == 'ü') c = 27; if (c == 'ö') c = 28; if (c == 'ä') c = 29; if (c == 'ß') c = 30; if (c == '.') c = 31; if (c >= 'a' && c <= 'z') c = (char)(c - 'a'); neu.setNextBit((c & 16) != 0); neu.setNextBit((c & 8) != 0); neu.setNextBit((c & 4) != 0); neu.setNextBit((c & 2) != 0); neu.setNextBit((c & 1) != 0); } // Chanels speichern neu.setNextBit((k.channels - 1) == 1); // Sample Rate speichern neu.schreibe((char*)&k.sampleRate, 4); // Datei Position schreiben neu.schreibe((char*)&k.datPos, 8); // Länge des Sounds Speichern int sLen = (int)(k.datEnd - k.datPos); neu.schreibe((char*)&sLen, 4); } // alte Sounds kopieren char* byte = new char[2048]; if (sAnz > 1) { if (!alt.open(Datei::Style::lesen)) { tmp.remove(); neu.close(); neu.remove(); sounds->remove(sAnz); cs.unlock(); return 0; } alt.setLPosition(hLen, 0); for (__int64 i = hLen; i < alt.getSize(); ) { int l = 2048; if (l > alt.getSize() - i) l = (int)(alt.getSize() - i); alt.lese(byte, l); neu.schreibe(byte, l); i += l; } alt.close(); } // Neuen Sound kopieren if (!tmp.open(Datei::Style::lesen)) { tmp.remove(); neu.close(); neu.remove(); sounds->remove(sAnz); cs.unlock(); return 0; } for (int i = 0; i < (int)tmp.getSize(); ) { int l = 2048; if (l > tmp.getSize() - i) l = (int)(tmp.getSize() - i); tmp.lese(byte, l); neu.schreibe(byte, l); i += l; } delete[] byte; tmp.close(); neu.close(); // Dateien Umbenennen und remove tmp.remove(); alt.remove(); neu.umbenennen(*pfad); leseDaten(); cs.unlock(); return 1; } // Löschen bool GSLDatei::removeSound(Framework::Text* name) { bool ret = removeSound(*name); name->release(); return ret; } bool GSLDatei::removeSound(const char* name) { cs.lock(); // Prüfen ob vorhanden int anz = sounds->getEintragAnzahl(); int num = -1; for (int i = 0; i < anz; i++) { if (sounds->get(i).name.istGleich(name)) { num = i; break; } } if (num < 0) { cs.unlock(); return 1; } Text neuPf = pfad->getText(); neuPf += "_"; GetFreePfad(&neuPf); Datei neu; neu.setDatei(neuPf); neu.erstellen(); if (!neu.open(Datei::Style::schreiben)) { cs.unlock(); return 0; } SoundKopf kpf = sounds->get(num); unsigned char sAnz = (unsigned char)(anz - 1); neu.schreibe((char*)&sAnz, 1); // Sound Köpfe speichern for (int i = 0; i <= sAnz; i++) { if (i == num) continue; SoundKopf k = sounds->get(i); k.datPos -= (140 + 5 * kpf.name.getLength()) / 8; k.datEnd -= (140 + 5 * kpf.name.getLength()) / 8; if (i > num) { k.datPos -= kpf.datEnd - kpf.datPos; k.datEnd -= kpf.datEnd - kpf.datPos; } int l = k.name.getLength(); // Namenslänge speichern neu.setNextBit((l & 8) != 0); neu.setNextBit((l & 4) != 0); neu.setNextBit((l & 2) != 0); neu.setNextBit((l & 1) != 0); for (int j = 0; j < l; j++) { // Name speichern char c = k.name.getText()[j]; if (c == 'ü') c = 27; if (c == 'ö') c = 28; if (c == 'ä') c = 29; if (c == 'ß') c = 30; if (c == '.') c = 31; if (c >= 'a' && c <= 'z') c = (char)(c - 'a'); neu.setNextBit((c & 16) != 0); neu.setNextBit((c & 8) != 0); neu.setNextBit((c & 4) != 0); neu.setNextBit((c & 2) != 0); neu.setNextBit((c & 1) != 0); } // Chanels speichern neu.setNextBit((k.channels - 1) == 1); // Sample Rate speichern neu.schreibe((char*)&k.sampleRate, 4); // Datei Position schreiben neu.schreibe((char*)&k.datPos, 8); // Länge des Sounds Speichern int sLen = (int)(k.datEnd - k.datPos); neu.schreibe((char*)&sLen, 4); } // Alte Sounds kopieren Datei alt; alt.setDatei(*pfad); if (sAnz) { if (!alt.open(Datei::Style::lesen)) { neu.close(); neu.remove(); cs.unlock(); return 0; } alt.setLPosition(neu.getSPosition() + (140 + 5 * kpf.name.getLength()) / 8, 0); char* byte = new char[2048]; for (__int64 i = alt.getLPosition(); i < kpf.datPos; ) { int l = 2048; if (l > kpf.datPos - i) l = (int)(kpf.datPos - i); alt.lese(byte, l); neu.schreibe(byte, l); i += l; } alt.setLPosition(kpf.datEnd, 0); for (__int64 i = alt.getLPosition(); i < alt.getSize(); ) { int l = 2048; if (l > alt.getSize() - i) l = (int)(alt.getSize() - i); alt.lese(byte, l); neu.schreibe(byte, l); i += l; } delete[] byte; alt.close(); } neu.close(); // Dateien Umbenennen und remove alt.remove(); neu.umbenennen(*pfad); leseDaten(); cs.unlock(); return 1; }