GSLDatei.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  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. : ReferenceCounter()
  12. {
  13. sounds = new Array< SoundKopf >();
  14. pfad = new Text();
  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(const 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(const 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, const char* name)
  147. {
  148. Text kName;
  149. for (const 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(const 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. }