123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- #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()
- {
- sounds = new Array< SoundKopf >();
- pfad = new Text();
- ref = 1;
- }
- // 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( 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( 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, char *name )
- {
- Text kName;
- for( 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( 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;
- }
- // Reference Counting
- GSLDateiV *GSLDatei::getThis()
- {
- ref++;
- return this;
- }
- GSLDateiV *GSLDatei::release()
- {
- ref--;
- if( !ref )
- delete this;
- return 0;
- }
|