|
@@ -0,0 +1,495 @@
|
|
|
+#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();
|
|
|
+ InitializeCriticalSection( &cs );
|
|
|
+ ref = 1;
|
|
|
+}
|
|
|
+
|
|
|
+// Destruktor
|
|
|
+GSLDatei::~GSLDatei()
|
|
|
+{
|
|
|
+ sounds->release();
|
|
|
+ pfad->release();
|
|
|
+ DeleteCriticalSection( &cs );
|
|
|
+}
|
|
|
+
|
|
|
+// Datei open
|
|
|
+void GSLDatei::setDatei( Framework::Text *txt )
|
|
|
+{
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ pfad->setText( txt );
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+}
|
|
|
+
|
|
|
+void GSLDatei::setDatei( char *txt )
|
|
|
+{
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ pfad->setText( txt );
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+}
|
|
|
+
|
|
|
+bool GSLDatei::leseDaten()
|
|
|
+{
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ sounds->leeren();
|
|
|
+ Datei d;
|
|
|
+ d.setDatei( *pfad );
|
|
|
+ if( !d.getSize() )
|
|
|
+ return 1;
|
|
|
+ if( !d.open( Datei::Style::lesen ) )
|
|
|
+ {
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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();
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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 )
|
|
|
+{
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ int anz = sounds->getEintragAnzahl();
|
|
|
+ for( int i = 0; i < anz; i++ )
|
|
|
+ {
|
|
|
+ if( sounds->get( i ).name.istGleich( name ) )
|
|
|
+ {
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ return new GSLSound( sounds->get( i ) );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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;
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ // Prüfen ob bereits vorhanden
|
|
|
+ int anz = sounds->getEintragAnzahl();
|
|
|
+ for( int i = 0; i < anz; i++ )
|
|
|
+ {
|
|
|
+ if( sounds->get( i ).name.istGleich( name ) )
|
|
|
+ {
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Text tmpPf = pfad->getText();
|
|
|
+ tmpPf += "_";
|
|
|
+ GetFreePfad( &tmpPf );
|
|
|
+ Datei tmp;
|
|
|
+ tmp.setDatei( tmpPf );
|
|
|
+ tmp.erstellen();
|
|
|
+ if( !tmp.open( Datei::Style::schreiben ) )
|
|
|
+ {
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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();
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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 );
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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 );
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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();
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+// Löschen
|
|
|
+bool GSLDatei::removeSound( Framework::Text *name )
|
|
|
+{
|
|
|
+ bool ret = removeSound( *name );
|
|
|
+ name->release();
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+bool GSLDatei::removeSound( char *name )
|
|
|
+{
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ // 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 )
|
|
|
+ {
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ Text neuPf = pfad->getText();
|
|
|
+ neuPf += "_";
|
|
|
+ GetFreePfad( &neuPf );
|
|
|
+ Datei neu;
|
|
|
+ neu.setDatei( neuPf );
|
|
|
+ neu.erstellen();
|
|
|
+ if( !neu.open( Datei::Style::schreiben ) )
|
|
|
+ {
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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();
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ 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();
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+// Reference Counting
|
|
|
+GSLDateiV *GSLDatei::getThis()
|
|
|
+{
|
|
|
+ ref++;
|
|
|
+ return this;
|
|
|
+}
|
|
|
+
|
|
|
+GSLDateiV *GSLDatei::release()
|
|
|
+{
|
|
|
+ ref--;
|
|
|
+ if( !ref )
|
|
|
+ delete this;
|
|
|
+ return 0;
|
|
|
+}
|