aRts audio server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

580 lines
13KB

  1. /*
  2. Copyright (C) 2000 Stefan Westerfeld
  3. stefan@space.twc.de
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public License
  13. along with this library; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. #include "config.h"
  18. #ifdef HAVE_LIBAUDIOFILE
  19. #include "artsflow.h"
  20. #include "stdsynthmodule.h"
  21. #include "debug.h"
  22. #include "cachedwav.h"
  23. #include "convert.h"
  24. #include <stdio.h>
  25. #include <iostream>
  26. #include <climits>
  27. #include <cstdlib>
  28. #include <cstring>
  29. extern "C" {
  30. /* Some versions of libaudiofile seem to lack the extern "C" declaration,
  31. * so you you may need that extra one.
  32. *
  33. * Other versions of libaudiofile seem to have two closing "}" in aupvlist.h,
  34. * so if you can't compile, this, check that /usr/include/aupvlist.h contains
  35. * something like that
  36. *
  37. * #ifdef __cplusplus
  38. * }
  39. * #endif
  40. *
  41. * only once not twice.
  42. */
  43. #include "audiofile.h"
  44. }
  45. #include <sys/stat.h>
  46. #include <unistd.h>
  47. using namespace std;
  48. using namespace Arts;
  49. CachedWav *CachedWav::load(Cache *cache, string filename)
  50. {
  51. CachedWav *wav;
  52. wav = (CachedWav *)cache->get(string("CachedWav:")+filename);
  53. if(!wav) {
  54. wav = new CachedWav(cache,filename);
  55. if(!wav->initOk) // loading failed
  56. {
  57. wav->decRef();
  58. return 0;
  59. }
  60. }
  61. return(wav);
  62. }
  63. bool CachedWav::isValid()
  64. {
  65. if(!initOk)
  66. return false;
  67. struct stat newstat;
  68. lstat(filename.c_str(),&newstat);
  69. return(newstat.st_mtime == oldstat.st_mtime);
  70. }
  71. int CachedWav::memoryUsage()
  72. {
  73. return(bufferSize);
  74. }
  75. CachedWav::CachedWav(Cache *cache, string filename) : CachedObject(cache),
  76. filename(filename),initOk(false), buffer(0)
  77. {
  78. int sampleFormat;
  79. AFframecount frameCount;
  80. AFfilehandle file;
  81. setKey(string("CachedWav:")+filename);
  82. if(lstat(filename.c_str(),&oldstat) == -1)
  83. {
  84. arts_info("CachedWav: Can't stat file '%s'", filename.c_str());
  85. return;
  86. }
  87. file = afOpenFile(filename.c_str(), "r", NULL);
  88. if(!file)
  89. {
  90. arts_info("CachedWav: Can't read file '%s'", filename.c_str());
  91. return;
  92. }
  93. frameCount = afGetFrameCount(file, AF_DEFAULT_TRACK);
  94. if(frameCount <= 0 || frameCount >= INT_MAX)
  95. {
  96. arts_info("CachedWav: Invalid length for '%s'", filename.c_str());
  97. afCloseFile(file);
  98. return;
  99. }
  100. channelCount = afGetChannels(file, AF_DEFAULT_TRACK);
  101. afGetSampleFormat(file, AF_DEFAULT_TRACK, &sampleFormat, &sampleWidth);
  102. // we want everything converted to little endian unconditionally
  103. afSetVirtualByteOrder(file,AF_DEFAULT_TRACK, AF_BYTEORDER_LITTLEENDIAN);
  104. arts_debug("loaded wav %s",filename.c_str());
  105. arts_debug(" sample format: %d, sample width: %d",
  106. sampleFormat,sampleWidth);
  107. arts_debug(" channelCount: %d",channelCount);
  108. arts_debug(" frameCount: %d",frameCount);
  109. // different handling required for other sample widths
  110. assert(sampleWidth == 16 || sampleWidth == 8);
  111. long frameSize = (sampleWidth/8)*channelCount;
  112. samplingRate = afGetRate(file, AF_DEFAULT_TRACK);
  113. /*
  114. * if we don't know the track bytes, we'll have to figure out ourselves
  115. * how many frames are stored here - it would be nicer if libaudiofile
  116. * let us know somehow whether the value returned for getFrameCount
  117. * means "don't know" or is really the correct length
  118. */
  119. int trackBytes = afGetTrackBytes(file, AF_DEFAULT_TRACK);
  120. if(trackBytes == -1)
  121. {
  122. arts_debug("unknown length");
  123. long fcount = 0, f = 0;
  124. list<void *> blocks;
  125. do
  126. {
  127. void *block = malloc(1024 * frameSize);
  128. f = afReadFrames(file, AF_DEFAULT_TRACK,block,1024);
  129. if(f > 0)
  130. {
  131. fcount += f;
  132. blocks.push_back(block);
  133. }
  134. else
  135. {
  136. free(block);
  137. }
  138. } while(f > 0);
  139. frameCount = fcount;
  140. arts_debug("figured out frameCount = %ld", fcount);
  141. bufferSize = frameCount * frameSize;
  142. buffer = new uchar[bufferSize];
  143. assert(buffer);
  144. // reassemble and free the blocks
  145. while(!blocks.empty())
  146. {
  147. void *block = blocks.front();
  148. blocks.pop_front();
  149. f = (fcount>1024)?1024:fcount;
  150. memcpy(&buffer[(frameCount-fcount)*frameSize],block,f*frameSize);
  151. fcount -= f;
  152. }
  153. assert(fcount == 0);
  154. }
  155. else
  156. {
  157. bufferSize = frameCount * frameSize;
  158. buffer = new uchar[bufferSize];
  159. assert(buffer);
  160. afReadFrames(file, AF_DEFAULT_TRACK,buffer,frameCount);
  161. }
  162. afCloseFile(file);
  163. initOk = true;
  164. }
  165. CachedWav::~CachedWav()
  166. {
  167. if(buffer)
  168. delete[] buffer;
  169. }
  170. namespace Arts {
  171. class Synth_PLAY_WAV_impl : public Synth_PLAY_WAV_skel, public StdSynthModule {
  172. protected:
  173. double flpos;
  174. float _speed;
  175. string _filename;
  176. bool _finished;
  177. CachedWav *cachedwav;
  178. void unload()
  179. {
  180. if(cachedwav)
  181. {
  182. cachedwav->decRef();
  183. cachedwav = 0;
  184. }
  185. }
  186. void load()
  187. {
  188. // unload the old file if necessary
  189. unload();
  190. // load the new (which will reset the position)
  191. cachedwav = CachedWav::load(Cache::the(), _filename);
  192. flpos = 0.0;
  193. }
  194. public:
  195. float speed() { return _speed; }
  196. void speed(float newSpeed) { _speed = newSpeed; }
  197. string filename() { return _filename; }
  198. void filename(const string& filename) { _filename = filename; load(); }
  199. void finished(bool f)
  200. {
  201. if(_finished != f)
  202. {
  203. _finished = f;
  204. finished_changed(f);
  205. }
  206. }
  207. bool finished() { return _finished; }
  208. Synth_PLAY_WAV_impl();
  209. ~Synth_PLAY_WAV_impl();
  210. void streamInit();
  211. void calculateBlock(unsigned long samples);
  212. };
  213. REGISTER_IMPLEMENTATION(Synth_PLAY_WAV_impl);
  214. }
  215. Synth_PLAY_WAV_impl::Synth_PLAY_WAV_impl()
  216. {
  217. cachedwav = 0;
  218. _speed = 1.0;
  219. _filename = "";
  220. _finished = false;
  221. }
  222. Synth_PLAY_WAV_impl::~Synth_PLAY_WAV_impl()
  223. {
  224. unload();
  225. }
  226. void Synth_PLAY_WAV_impl::streamInit()
  227. {
  228. finished(false);
  229. }
  230. void Synth_PLAY_WAV_impl::calculateBlock(unsigned long samples)
  231. {
  232. unsigned long haveSamples = 0;
  233. if(cachedwav)
  234. {
  235. double speed = cachedwav->samplingRate / samplingRateFloat * _speed;
  236. haveSamples = uni_convert_stereo_2float(samples, cachedwav->buffer,
  237. cachedwav->bufferSize,cachedwav->channelCount,cachedwav->sampleWidth,
  238. left,right,speed,flpos);
  239. flpos += (double)haveSamples * speed;
  240. }
  241. if(haveSamples != samples)
  242. {
  243. unsigned long i;
  244. for(i=haveSamples;i<samples;i++)
  245. left[i] = right[i] = 0.0;
  246. finished(true);
  247. }
  248. /*
  249. float speed = 0.0;
  250. unsigned long haveSamples = 0;
  251. if(cachedwav)
  252. {
  253. float allSamples = cachedwav->bufferSize*8 /
  254. cachedwav->sampleWidth/cachedwav->channelCount;
  255. float fHaveSamples = allSamples - flpos;
  256. speed = cachedwav->samplingRate / (float)samplingRate * _speed;
  257. fHaveSamples /= speed;
  258. fHaveSamples -= 2.0; // one due to interpolation and another against
  259. // rounding errors
  260. if(fHaveSamples > 0)
  261. {
  262. haveSamples = (int)fHaveSamples;
  263. if(haveSamples > samples) haveSamples = samples;
  264. }
  265. }
  266. if(haveSamples) // something left to play?
  267. {
  268. if(cachedwav->channelCount == 1)
  269. {
  270. if(cachedwav->sampleWidth == 16) {
  271. interpolate_mono_16le_float(haveSamples,
  272. flpos,speed,cachedwav->buffer,left);
  273. }
  274. else {
  275. interpolate_mono_8_float(haveSamples,
  276. flpos,speed,cachedwav->buffer,left);
  277. }
  278. memcpy(right,left,sizeof(float)*haveSamples);
  279. }
  280. else if(cachedwav->channelCount == 2)
  281. {
  282. if(cachedwav->sampleWidth == 16) {
  283. interpolate_stereo_i16le_2float(haveSamples,
  284. flpos,speed,cachedwav->buffer,left,right);
  285. }
  286. else {
  287. interpolate_stereo_i8_2float(haveSamples,
  288. flpos,speed,cachedwav->buffer,left,right);
  289. }
  290. } else {
  291. assert(false);
  292. }
  293. flpos += (float)haveSamples * speed;
  294. }
  295. if(haveSamples != samples)
  296. {
  297. unsigned long i;
  298. for(i=haveSamples;i<samples;i++)
  299. left[i] = right[i] = 0.0;
  300. _finished = true;
  301. }
  302. */
  303. }
  304. #if 0
  305. class Synth_PLAY_WAV :public SynthModule {
  306. protected:
  307. CachedWav *cachedwav;
  308. unsigned char *buffer;
  309. int channelCount;
  310. unsigned long bufferSize, position, bytesPerSample;
  311. // inputs:
  312. enum { PROP_FILENAME };
  313. // outputs:
  314. enum { LEFT, RIGHT, DONE };
  315. public:
  316. void Initialize();
  317. void DeInitialize();
  318. void Calculate() { assert(false); }
  319. void CalculateBlock(unsigned long samples);
  320. string getParams() { return("_filename;left,right,done"); }
  321. static void *Creator() { return new Synth_PLAY_WAV; }
  322. };
  323. ModuleClient MC_Synth_PLAY_WAV(SynthModule::get_MS,"Synth_PLAY_WAV",Synth_PLAY_WAV::Creator);
  324. void Synth_PLAY_WAV::CalculateBlock(unsigned long samples)
  325. {
  326. unsigned long haveSamples = samples;
  327. unsigned long remainingSamples;
  328. remainingSamples = (bufferSize-position)/bytesPerSample;
  329. if(haveSamples > remainingSamples) haveSamples = remainingSamples;
  330. float *left = out[LEFT], *right = out[RIGHT], *done = out[DONE];
  331. unsigned long i;
  332. if(haveSamples)
  333. {
  334. if(channelCount == 1)
  335. {
  336. if(bytesPerSample == 2) {
  337. convert_mono_16le_float(haveSamples,&buffer[position],left);
  338. }
  339. else {
  340. convert_mono_8_float(haveSamples,&buffer[position],left);
  341. }
  342. memcpy(right,left,sizeof(float)*haveSamples);
  343. }
  344. else if(channelCount == 2)
  345. {
  346. if(bytesPerSample == 2) {
  347. convert_stereo_i16le_2float(haveSamples,&buffer[position],
  348. left,right);
  349. }
  350. else {
  351. convert_stereo_i8_2float(haveSamples,&buffer[position],
  352. left,right);
  353. }
  354. } else {
  355. assert(false);
  356. }
  357. for(i=0;i<haveSamples;i++) done[i] = 0.0;
  358. position += bytesPerSample*channelCount*haveSamples;
  359. }
  360. for(i=haveSamples;i<samples;i++)
  361. {
  362. left[i] = right[i] = 0.0; done[i] = 1.0; // ready, kill me ;)
  363. }
  364. }
  365. void Synth_PLAY_WAV::DeInitialize()
  366. {
  367. cachedwav->decRef();
  368. }
  369. void Synth_PLAY_WAV::Initialize()
  370. {
  371. cachedwav = CachedWav::load(Synthesizer->getCache(),
  372. getStringProperty(PROP_FILENAME));
  373. // may take some speed to access cachedwav every time
  374. bufferSize = cachedwav->bufferSize;
  375. channelCount = cachedwav->channelCount;
  376. buffer = cachedwav->buffer;
  377. bytesPerSample = cachedwav->sampleWidth/8;
  378. haveCalculateBlock = true;
  379. position = 0;
  380. }
  381. class Synth_PLAY_PITCHED_WAV :public SynthModule {
  382. protected:
  383. CachedWav *cachedwav;
  384. float flpos;
  385. // inputs:
  386. enum { FREQUENCY,RECFREQUENCY, PROP_FILENAME };
  387. // outputs:
  388. enum { LEFT, RIGHT, DONE };
  389. public:
  390. void Initialize();
  391. void DeInitialize();
  392. void Calculate() { assert(false); }
  393. void CalculateBlock(unsigned long samples);
  394. string getParams() { return("frequency,recfrequency,_filename;left,right,done"); }
  395. static void *Creator() { return new Synth_PLAY_PITCHED_WAV; }
  396. };
  397. ModuleClient MC_Synth_PLAY_PITCHED_WAV(SynthModule::get_MS,"Synth_PLAY_PITCHED_WAV",Synth_PLAY_PITCHED_WAV::Creator);
  398. void Synth_PLAY_PITCHED_WAV::CalculateBlock(unsigned long samples)
  399. {
  400. float frequency = in[FREQUENCY][0], recfrequency = in[RECFREQUENCY][0];
  401. float allSamples = cachedwav->bufferSize*8 /
  402. cachedwav->sampleWidth/cachedwav->channelCount;
  403. float fHaveSamples = allSamples - flpos;
  404. float speed = cachedwav->samplingRate / (float)samplingRate *
  405. frequency / recfrequency;
  406. fHaveSamples /= speed;
  407. fHaveSamples -= 2.0; // one due to interpolation and another against
  408. // rounding errors
  409. unsigned long haveSamples;
  410. if(fHaveSamples < 0)
  411. {
  412. haveSamples = 0;
  413. }
  414. else
  415. {
  416. haveSamples = fHaveSamples;
  417. if(haveSamples > samples) haveSamples = samples;
  418. }
  419. float *left = out[LEFT], *right = out[RIGHT], *done = out[DONE];
  420. unsigned long i;
  421. if(haveSamples)
  422. {
  423. if(cachedwav->channelCount == 1)
  424. {
  425. if(cachedwav->sampleWidth == 16) {
  426. interpolate_mono_16le_float(haveSamples,
  427. flpos,speed,cachedwav->buffer,left);
  428. }
  429. else {
  430. interpolate_mono_8_float(haveSamples,
  431. flpos,speed,cachedwav->buffer,left);
  432. }
  433. memcpy(right,left,sizeof(float)*haveSamples);
  434. }
  435. else if(cachedwav->channelCount == 2)
  436. {
  437. if(cachedwav->sampleWidth == 16) {
  438. interpolate_stereo_i16le_2float(haveSamples,
  439. flpos,speed,cachedwav->buffer,left,right);
  440. }
  441. else {
  442. interpolate_stereo_i8_2float(haveSamples,
  443. flpos,speed,cachedwav->buffer,left,right);
  444. }
  445. } else {
  446. assert(false);
  447. }
  448. for(i=0;i<haveSamples;i++) done[i] = 0.0;
  449. flpos += (float)haveSamples * speed;
  450. }
  451. for(i=haveSamples;i<samples;i++)
  452. {
  453. left[i] = right[i] = 0.0; done[i] = 1.0; // ready, kill me ;)
  454. }
  455. }
  456. void Synth_PLAY_PITCHED_WAV::DeInitialize()
  457. {
  458. cachedwav->decRef();
  459. }
  460. void Synth_PLAY_PITCHED_WAV::Initialize()
  461. {
  462. cachedwav = CachedWav::load(Synthesizer->getCache(),
  463. getStringProperty(PROP_FILENAME));
  464. haveCalculateBlock = true;
  465. flpos = 0.0;
  466. }
  467. #endif
  468. #else
  469. #ifdef __GNUC__
  470. #warning "No libaudiofile available, that means, you won't be able to play wavs"
  471. #endif
  472. #endif