GSLDatei.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. #include "GSLDatei.h"
  2. #ifdef WIN32
  3. #include "Sound.h"
  4. #else
  5. #include "Sound.h"
  6. #endif
  7. using namespace GSL;
  8. // Inhalt der GSLDatei Klasse aus GSLDatei.h
  9. // Konstruktor
  10. GSLDatei::GSLDatei()
  11. {
  12. sounds = new Array< SoundKopf >();
  13. pfad = new Text();
  14. ref = 1;
  15. }
  16. // Destruktor
  17. GSLDatei::~GSLDatei()
  18. {
  19. sounds->release();
  20. pfad->release();
  21. }
  22. // Datei open
  23. void GSLDatei::setDatei( Framework::Text *txt )
  24. {
  25. cs.lock();
  26. pfad->setText( txt );
  27. cs.unlock();
  28. }
  29. void GSLDatei::setDatei( char *txt )
  30. {
  31. cs.lock();
  32. pfad->setText( txt );
  33. cs.unlock();
  34. }
  35. bool GSLDatei::leseDaten()
  36. {
  37. cs.lock();
  38. sounds->leeren();
  39. Datei d;
  40. d.setDatei( *pfad );
  41. if( !d.getSize() )
  42. {
  43. cs.unlock();
  44. return 1;
  45. }
  46. if( !d.open( Datei::Style::lesen ) )
  47. {
  48. cs.unlock();
  49. return 0;
  50. }
  51. unsigned char sAnz = 0;
  52. d.lese( (char*)&sAnz, 1 );
  53. // Datei Sound - Köpfe einlesen
  54. for( int i = 0; i < sAnz; i++ )
  55. {
  56. SoundKopf kpf;
  57. bool bit = 0;
  58. char len = 0;
  59. // Namenslänge lesen
  60. for( int i = 0; i < 4; i++ )
  61. {
  62. d.getNextBit( bit );
  63. len = (char)( len | ( ( (char)bit << ( 3 - i ) ) & ( 1 << ( 3 - i ) ) ) );
  64. }
  65. len &= 15;
  66. // Name lesen
  67. for( int i = 0; i < len; i++ )
  68. {
  69. char zeichen = 0;
  70. for( int j = 0; j < 5; j++ )
  71. {
  72. d.getNextBit( bit );
  73. zeichen = (char)( zeichen | ( ( (char)bit << ( 4 - j ) ) & ( 1 << ( 4 - j ) ) ) );
  74. }
  75. zeichen &= 31;
  76. if( zeichen == 27 )
  77. zeichen = 'ü';
  78. if( zeichen == 28 )
  79. zeichen = 'ö';
  80. if( zeichen == 29 )
  81. zeichen = 'ä';
  82. if( zeichen == 30 )
  83. zeichen = 'ß';
  84. if( zeichen == 31 )
  85. zeichen = '.';
  86. if( zeichen < 27 )
  87. zeichen = (char)( zeichen + 'a' );
  88. kpf.name.append( &zeichen, 1 );
  89. } // Chanel Anzahl lesen
  90. d.getNextBit( bit );
  91. kpf.channels = (char)( bit + 1 );
  92. // Sample Rate lesen
  93. d.lese( (char*)&kpf.sampleRate, 4 );
  94. // Position des Sounds in der Datei lesen
  95. d.lese( (char*)&kpf.datPos, 8 );
  96. // Länge des Sounds lesen
  97. int sLen = 0;
  98. d.lese( (char*)&sLen, 4 );
  99. kpf.datEnd = kpf.datPos + sLen;
  100. kpf.pfad = pfad->getText();
  101. sounds->add( kpf );
  102. }
  103. d.close();
  104. cs.unlock();
  105. return 1;
  106. }
  107. int GSLDatei::getSoundAnzahl()
  108. {
  109. return sounds->getEintragAnzahl();
  110. }
  111. Text *GSLDatei::getSoundName( int num )
  112. {
  113. if( !sounds->hat( num ) )
  114. return 0;
  115. return new Text( sounds->get( num ).name );
  116. }
  117. // Laden
  118. GSLSoundV *GSLDatei::getSound( Framework::Text *name )
  119. {
  120. GSLSoundV *ret = getSound( *name );
  121. name->release();
  122. return ret;
  123. }
  124. GSLSoundV *GSLDatei::getSound( char *name )
  125. {
  126. cs.lock();
  127. int anz = sounds->getEintragAnzahl();
  128. for( int i = 0; i < anz; i++ )
  129. {
  130. if( sounds->get( i ).name.istGleich( name ) )
  131. {
  132. cs.unlock();
  133. return new GSLSound( sounds->get( i ) );
  134. }
  135. }
  136. cs.unlock();
  137. return 0;
  138. }
  139. // Speichern
  140. bool GSLDatei::speicherSound( GSLSoundV *zSound, Framework::Text *name )
  141. {
  142. bool ret = speicherSound( zSound, *name );
  143. name->release();
  144. return ret;
  145. }
  146. bool GSLDatei::speicherSound( GSLSoundV *zSound, char *name )
  147. {
  148. Text kName;
  149. for( char *c = name; *c; ++c )
  150. {
  151. if( *c >= 'A' && *c <= 'Z' )
  152. kName.append( (char)( *c + 32 ) );
  153. if( *c >= 'a' && *c <= 'z' )
  154. kName.append( *c );
  155. if( *c == 'Ü' || *c == 'ü' )
  156. kName.append( 'ü' );
  157. if( *c == 'Ö' || *c == 'ö' )
  158. kName.append( 'ö' );
  159. if( *c == 'Ä' || *c == 'ä' )
  160. kName.append( 'ä' );
  161. if( *c == 'ß' )
  162. kName.append( 'ß' );
  163. if( *c == '.' )
  164. kName.append( '.' );
  165. if( kName.getLength() == 15 )
  166. break;
  167. }
  168. name = kName;
  169. cs.lock();
  170. // Prüfen ob bereits vorhanden
  171. int anz = sounds->getEintragAnzahl();
  172. for( int i = 0; i < anz; i++ )
  173. {
  174. if( sounds->get( i ).name.istGleich( name ) )
  175. {
  176. cs.unlock();
  177. return 0;
  178. }
  179. }
  180. Text tmpPf = pfad->getText();
  181. tmpPf += "_";
  182. GetFreePfad( &tmpPf );
  183. Datei tmp;
  184. tmp.setDatei( tmpPf );
  185. tmp.erstellen();
  186. if( !tmp.open( Datei::Style::schreiben ) )
  187. {
  188. cs.unlock();
  189. return 0;
  190. }
  191. char *buffer = new char[ 0x4000 ];
  192. // Neuen Sound in Temporäre Datei schreiben
  193. zSound->open();
  194. while( 1 )
  195. {
  196. int len = 0;
  197. if( ( len = zSound->getDaten( buffer, 0x4000 ) ) < 0 )
  198. break;
  199. tmp.schreibe( buffer, len );
  200. }
  201. zSound->close();
  202. delete buffer;
  203. tmp.close();
  204. int hLen = 1;
  205. unsigned char sAnz = (unsigned char)sounds->getEintragAnzahl();
  206. // Sound Kopf Länge errechnen
  207. for( int i = 0; i < sAnz; i++ )
  208. {
  209. SoundKopf kpf = sounds->get( i );
  210. hLen += ( 140 + 5 * kpf.name.getLength() ) / 8;
  211. }
  212. Datei alt;
  213. alt.setDatei( *pfad );
  214. // Sound Kopf Erstellen
  215. SoundKopf kpf;
  216. kpf.channels = (char)( !zSound->istMono() + 1 );
  217. kpf.name = name;
  218. kpf.pfad = pfad->getText();
  219. kpf.sampleRate = zSound->getSampleRate();
  220. kpf.datPos = ( alt.getSize() <= 0 ? 1 : alt.getSize() );
  221. kpf.datEnd = tmp.getSize() + kpf.datPos;
  222. sounds->add( kpf );
  223. Text neuPf = pfad->getText();
  224. neuPf += "_";
  225. GetFreePfad( &neuPf );
  226. Datei neu;
  227. neu.setDatei( neuPf );
  228. neu.erstellen();
  229. if( !neu.open( Datei::Style::schreiben ) )
  230. {
  231. sounds->remove( sAnz );
  232. tmp.remove();
  233. cs.unlock();
  234. return 0;
  235. }
  236. sAnz = (unsigned char)sounds->getEintragAnzahl();
  237. neu.schreibe( (char*)&sAnz, 1 );
  238. // Sound Köpfe speichern
  239. for( int i = 0; i < sAnz; i++ )
  240. {
  241. SoundKopf k = sounds->get( i );
  242. k.datPos += ( 140 + 5 * kpf.name.getLength() ) / 8;
  243. k.datEnd += ( 140 + 5 * kpf.name.getLength() ) / 8;
  244. int l = k.name.getLength();
  245. // Namenslänge speichern
  246. neu.setNextBit( ( l & 8 ) != 0 );
  247. neu.setNextBit( ( l & 4 ) != 0 );
  248. neu.setNextBit( ( l & 2 ) != 0 );
  249. neu.setNextBit( ( l & 1 ) != 0 );
  250. for( int j = 0; j < l; j++ )
  251. { // Name speichern
  252. char c = k.name.getText()[ j ];
  253. if( c == 'ü' )
  254. c = 27;
  255. if( c == 'ö' )
  256. c = 28;
  257. if( c == 'ä' )
  258. c = 29;
  259. if( c == 'ß' )
  260. c = 30;
  261. if( c == '.' )
  262. c = 31;
  263. if( c >= 'a' && c <= 'z' )
  264. c = (char)( c - 'a' );
  265. neu.setNextBit( ( c & 16 ) != 0 );
  266. neu.setNextBit( ( c & 8 ) != 0 );
  267. neu.setNextBit( ( c & 4 ) != 0 );
  268. neu.setNextBit( ( c & 2 ) != 0 );
  269. neu.setNextBit( ( c & 1 ) != 0 );
  270. } // Chanels speichern
  271. neu.setNextBit( ( k.channels - 1 ) == 1 );
  272. // Sample Rate speichern
  273. neu.schreibe( (char*)&k.sampleRate, 4 );
  274. // Datei Position schreiben
  275. neu.schreibe( (char*)&k.datPos, 8 );
  276. // Länge des Sounds Speichern
  277. int sLen = (int)( k.datEnd - k.datPos );
  278. neu.schreibe( (char*)&sLen, 4 );
  279. }
  280. // alte Sounds kopieren
  281. char *byte = new char[ 2048 ];
  282. if( sAnz > 1 )
  283. {
  284. if( !alt.open( Datei::Style::lesen ) )
  285. {
  286. tmp.remove();
  287. neu.close();
  288. neu.remove();
  289. sounds->remove( sAnz );
  290. cs.unlock();
  291. return 0;
  292. }
  293. alt.setLPosition( hLen, 0 );
  294. for( __int64 i = hLen; i < alt.getSize(); )
  295. {
  296. int l = 2048;
  297. if( l > alt.getSize() - i )
  298. l = (int)( alt.getSize() - i );
  299. alt.lese( byte, l );
  300. neu.schreibe( byte, l );
  301. i += l;
  302. }
  303. alt.close();
  304. }
  305. // Neuen Sound kopieren
  306. if( !tmp.open( Datei::Style::lesen ) )
  307. {
  308. tmp.remove();
  309. neu.close();
  310. neu.remove();
  311. sounds->remove( sAnz );
  312. cs.unlock();
  313. return 0;
  314. }
  315. for( int i = 0; i < (int)tmp.getSize(); )
  316. {
  317. int l = 2048;
  318. if( l > tmp.getSize() - i )
  319. l = (int)( tmp.getSize() - i );
  320. tmp.lese( byte, l );
  321. neu.schreibe( byte, l );
  322. i += l;
  323. }
  324. delete[] byte;
  325. tmp.close();
  326. neu.close();
  327. // Dateien Umbenennen und remove
  328. tmp.remove();
  329. alt.remove();
  330. neu.umbenennen( *pfad );
  331. leseDaten();
  332. cs.unlock();
  333. return 1;
  334. }
  335. // Löschen
  336. bool GSLDatei::removeSound( Framework::Text *name )
  337. {
  338. bool ret = removeSound( *name );
  339. name->release();
  340. return ret;
  341. }
  342. bool GSLDatei::removeSound( char *name )
  343. {
  344. cs.lock();
  345. // Prüfen ob vorhanden
  346. int anz = sounds->getEintragAnzahl();
  347. int num = -1;
  348. for( int i = 0; i < anz; i++ )
  349. {
  350. if( sounds->get( i ).name.istGleich( name ) )
  351. {
  352. num = i;
  353. break;
  354. }
  355. }
  356. if( num < 0 )
  357. {
  358. cs.unlock();
  359. return 1;
  360. }
  361. Text neuPf = pfad->getText();
  362. neuPf += "_";
  363. GetFreePfad( &neuPf );
  364. Datei neu;
  365. neu.setDatei( neuPf );
  366. neu.erstellen();
  367. if( !neu.open( Datei::Style::schreiben ) )
  368. {
  369. cs.unlock();
  370. return 0;
  371. }
  372. SoundKopf kpf = sounds->get( num );
  373. unsigned char sAnz = (unsigned char)( anz - 1 );
  374. neu.schreibe( (char*)&sAnz, 1 );
  375. // Sound Köpfe speichern
  376. for( int i = 0; i <= sAnz; i++ )
  377. {
  378. if( i == num )
  379. continue;
  380. SoundKopf k = sounds->get( i );
  381. k.datPos -= ( 140 + 5 * kpf.name.getLength() ) / 8;
  382. k.datEnd -= ( 140 + 5 * kpf.name.getLength() ) / 8;
  383. if( i > num )
  384. {
  385. k.datPos -= kpf.datEnd - kpf.datPos;
  386. k.datEnd -= kpf.datEnd - kpf.datPos;
  387. }
  388. int l = k.name.getLength();
  389. // Namenslänge speichern
  390. neu.setNextBit( ( l & 8 ) != 0 );
  391. neu.setNextBit( ( l & 4 ) != 0 );
  392. neu.setNextBit( ( l & 2 ) != 0 );
  393. neu.setNextBit( ( l & 1 ) != 0 );
  394. for( int j = 0; j < l; j++ )
  395. { // Name speichern
  396. char c = k.name.getText()[ j ];
  397. if( c == 'ü' )
  398. c = 27;
  399. if( c == 'ö' )
  400. c = 28;
  401. if( c == 'ä' )
  402. c = 29;
  403. if( c == 'ß' )
  404. c = 30;
  405. if( c == '.' )
  406. c = 31;
  407. if( c >= 'a' && c <= 'z' )
  408. c = (char)( c - 'a' );
  409. neu.setNextBit( ( c & 16 ) != 0 );
  410. neu.setNextBit( ( c & 8 ) != 0 );
  411. neu.setNextBit( ( c & 4 ) != 0 );
  412. neu.setNextBit( ( c & 2 ) != 0 );
  413. neu.setNextBit( ( c & 1 ) != 0 );
  414. } // Chanels speichern
  415. neu.setNextBit( ( k.channels - 1 ) == 1 );
  416. // Sample Rate speichern
  417. neu.schreibe( (char*)&k.sampleRate, 4 );
  418. // Datei Position schreiben
  419. neu.schreibe( (char*)&k.datPos, 8 );
  420. // Länge des Sounds Speichern
  421. int sLen = (int)( k.datEnd - k.datPos );
  422. neu.schreibe( (char*)&sLen, 4 );
  423. }
  424. // Alte Sounds kopieren
  425. Datei alt;
  426. alt.setDatei( *pfad );
  427. if( sAnz )
  428. {
  429. if( !alt.open( Datei::Style::lesen ) )
  430. {
  431. neu.close();
  432. neu.remove();
  433. cs.unlock();
  434. return 0;
  435. }
  436. alt.setLPosition( neu.getSPosition() + ( 140 + 5 * kpf.name.getLength() ) / 8, 0 );
  437. char *byte = new char[ 2048 ];
  438. for( __int64 i = alt.getLPosition(); i < kpf.datPos; )
  439. {
  440. int l = 2048;
  441. if( l > kpf.datPos - i )
  442. l = (int)( kpf.datPos - i );
  443. alt.lese( byte, l );
  444. neu.schreibe( byte, l );
  445. i += l;
  446. }
  447. alt.setLPosition( kpf.datEnd, 0 );
  448. for( __int64 i = alt.getLPosition(); i < alt.getSize(); )
  449. {
  450. int l = 2048;
  451. if( l > alt.getSize() - i )
  452. l = (int)( alt.getSize() - i );
  453. alt.lese( byte, l );
  454. neu.schreibe( byte, l );
  455. i += l;
  456. }
  457. delete[] byte;
  458. alt.close();
  459. }
  460. neu.close();
  461. // Dateien Umbenennen und remove
  462. alt.remove();
  463. neu.umbenennen( *pfad );
  464. leseDaten();
  465. cs.unlock();
  466. return 1;
  467. }
  468. // Reference Counting
  469. GSLDateiV *GSLDatei::getThis()
  470. {
  471. ref++;
  472. return this;
  473. }
  474. GSLDateiV *GSLDatei::release()
  475. {
  476. ref--;
  477. if( !ref )
  478. delete this;
  479. return 0;
  480. }