123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- #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;
- }
|