Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
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.

621 lines
16KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2008 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. /*
  19. peakfile reading/writing.
  20. Here's how it works:
  21. Peakfiles are of the form 'name-[chunksize].peak', and contain
  22. floating point min/max pairs for an entire soundfile at a certain
  23. chunksize.
  24. It gets a little complicated because peakfiles are generated
  25. asynchronously and streamed to disk when capturing.
  26. When the GUI requests the peaks for a range of samples at a certain
  27. chunksize, a search is performed for a peakfile--starting with the
  28. requested chunksize, and then moving to smaller chunksizes--that
  29. exists and contains the peaks for the requested range (which it may
  30. not--if the peaks are in the process of being written). The peaks,
  31. if available, are then read from disk, downsampled to the exact
  32. chunksize requested, and displayed.
  33. On the generation end, peaks are either streamed to disk while
  34. recording (and therefore more or less in real time), or a process
  35. is forked to generate the entire peak file (either directly from
  36. the source, or from a higher-resolution peak file that exists and
  37. is complete).
  38. The end result is that peaks are:
  39. * read synchronously
  40. * generated asynchronously
  41. * cached at many resolutions
  42. */
  43. #include "Peaks.H"
  44. // #include "Timeline.H"
  45. #include <sys/mman.h>
  46. #include <sys/types.h>
  47. #include <sys/stat.h>
  48. #include <unistd.h>
  49. #include <fcntl.h>
  50. #include <stdlib.h>
  51. #include <stdio.h>
  52. #include <string.h>
  53. #include "Audio_File.H"
  54. #include "assert.h"
  55. #include <math.h>
  56. #include <FL/Fl.H> // for Fl::check();
  57. #include "debug.h"
  58. Peaks::peakbuffer Peaks::_peakbuf;
  59. bool Peaks::mipmapped_peakfiles = true;
  60. /* chunksizes at which to generate peakfiles (on demand). This should
  61. pretty much cover the usable range. Better performance can be
  62. achieved at high zoom-levels and for compressed sources with a
  63. minimum of 64, but those files are up into the megabytes. */
  64. const int Peaks::cache_minimum = 256; /* minimum chunksize to build peakfiles for */
  65. const int Peaks::cache_levels = 8; /* number of sampling levels in peak cache */
  66. // const int Peaks::cache_step = 2; /* powers of two between each level. 4 == 256, 2048, 16384, ... */
  67. const int Peaks::cache_step = 1; /* powers of two between each level. 4 == 256, 2048, 16384, ... */
  68. /* Peaks ( ) */
  69. /* { */
  70. /* _clip = NULL; */
  71. /* } */
  72. Peaks::Peaks ( Audio_File *c )
  73. {
  74. _clip = c;
  75. _peak_writer = NULL;
  76. }
  77. Peaks::~Peaks ( )
  78. {
  79. if ( _peak_writer )
  80. delete _peak_writer;
  81. }
  82. static
  83. const char *
  84. peakname ( const char *filename, nframes_t chunksize )
  85. {
  86. static char file[512];
  87. snprintf( file, 512, "%s-[%d].peak", filename, chunksize );
  88. return (const char*)&file;
  89. }
  90. /** Prepare a buffer of peaks from /s/ to /e/ for reading. Must be
  91. * called before any calls to operator[] */
  92. int
  93. Peaks::fill_buffer ( float fpp, nframes_t s, nframes_t e ) const
  94. {
  95. _fpp = fpp;
  96. return read_peaks( s, e, (e - s) / fpp, fpp );
  97. }
  98. static int
  99. nearest_power_of_two ( int v )
  100. {
  101. int p = 1;
  102. while ( 1 << p < v )
  103. ++p;
  104. return 1 << p;
  105. }
  106. static nframes_t
  107. nearest_cached_chunksize ( nframes_t chunksize )
  108. {
  109. nframes_t r = nearest_power_of_two( chunksize );
  110. for ( int i = Peaks::cache_levels; i--; r >>= Peaks::cache_step )
  111. if ( chunksize >= r )
  112. return r;
  113. return 0;
  114. }
  115. class Peakfile
  116. {
  117. FILE *_fp;
  118. nframes_t _chunksize;
  119. int _channels;
  120. const char *_name;
  121. public:
  122. Peakfile ( )
  123. {
  124. _fp = NULL;
  125. _chunksize = 0;
  126. _channels = 0;
  127. _name =NULL;
  128. }
  129. ~Peakfile ( )
  130. {
  131. if ( _fp )
  132. close();
  133. }
  134. /** convert frame number of peak number */
  135. nframes_t frame_to_peak ( nframes_t frame )
  136. {
  137. /* how many powers of two is chunksize > cache_minimum?
  138. skip clip size of peaks at increasing powers of two until
  139. we reach the closest one less than chunksize. Then
  140. address normally.*/
  141. return frame * _channels / _chunksize;
  142. }
  143. /** return the number of peaks in already open peakfile /fp/ */
  144. nframes_t
  145. npeaks ( void ) const
  146. {
  147. struct stat st;
  148. fstat( fileno( _fp ), &st );
  149. return st.st_size / sizeof( Peak );
  150. }
  151. /** returns true if the peakfile contains /npeaks/ peaks starting at sample /s/ */
  152. bool
  153. contains ( nframes_t start, nframes_t npeaks )
  154. {
  155. return frame_to_peak( start ) + npeaks <= this->npeaks();
  156. }
  157. /** given soundfile name /name/, try to open the best peakfile for /chunksize/ */
  158. bool
  159. open ( const char *name, nframes_t chunksize, int channels )
  160. {
  161. _channels = channels;
  162. _name = name;
  163. for ( _chunksize = nearest_cached_chunksize( chunksize );
  164. _chunksize >= Peaks::cache_minimum; _chunksize >>= Peaks::cache_step )
  165. if ( ( _fp = fopen( peakname( name, _chunksize ), "r" ) ) )
  166. break;
  167. return _fp != NULL;
  168. }
  169. bool
  170. open ( FILE *fp, int channels, nframes_t chunksize )
  171. {
  172. _fp = fp;
  173. _chunksize = chunksize;
  174. _channels = channels;
  175. }
  176. void
  177. leave_open ( void )
  178. {
  179. _fp = NULL;
  180. }
  181. void
  182. close ( void )
  183. {
  184. fclose( _fp );
  185. _fp = NULL;
  186. }
  187. /** read /npeaks/ peaks at /chunksize/ starting at sample /s/
  188. * assuming the peakfile contains data for /channels/
  189. * channels. Place the result in buffer /peaks/, which must be
  190. * large enough to fit the entire request. Returns the number of
  191. * peaks actually read, which may be fewer than were requested. */
  192. int
  193. read_peaks ( Peak *peaks, nframes_t s, int npeaks, nframes_t chunksize )
  194. {
  195. if ( ! _fp )
  196. return 0;
  197. const unsigned int ratio = chunksize / _chunksize;
  198. /* locate to start position */
  199. if ( fseek( _fp, frame_to_peak( s ) * sizeof( Peak ), SEEK_SET ) )
  200. /* failed to seek... peaks not ready? */
  201. return 0;
  202. if ( ratio == 1 )
  203. {
  204. int len = fread( peaks, sizeof( Peak ) * _channels, npeaks, _fp );
  205. // close;
  206. return len;
  207. }
  208. Peak *pbuf = new Peak[ ratio * _channels ];
  209. size_t len = 0;
  210. int i;
  211. for ( i = 0; i < npeaks; ++i )
  212. {
  213. /* read in a buffer */
  214. len = fread( pbuf, sizeof( Peak ) * _channels, ratio, _fp );
  215. Peak *pk = peaks + (i * _channels);
  216. /* get the peak for each channel */
  217. for ( int j = 0; j < _channels; ++j )
  218. {
  219. Peak *p = &pk[ j ];
  220. p->min = 0;
  221. p->max = 0;
  222. const Peak *pb = pbuf + j;
  223. for ( int k = len; k--; pb += _channels )
  224. {
  225. if ( pb->max > p->max )
  226. p->max = pb->max;
  227. if ( pb->min < p->min )
  228. p->min = pb->min;
  229. }
  230. }
  231. if ( len < ratio )
  232. break;
  233. }
  234. delete[] pbuf;
  235. // close();
  236. return i;
  237. }
  238. };
  239. int
  240. Peaks::read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, nframes_t chunksize ) const
  241. {
  242. nframes_t ncc = nearest_cached_chunksize( chunksize );
  243. if ( ! _peak_writer && ! current( cache_minimum ) )
  244. /* Build peaks asyncronously */
  245. if ( ! fork() )
  246. exit( make_peaks( ) );
  247. else
  248. return 0;
  249. Peakfile _peakfile;
  250. if ( ! _peakfile.open( _clip->name(), chunksize, _clip->channels() ) )
  251. return 0;
  252. else if ( ! _peakfile.contains( s, npeaks ) )
  253. {
  254. /* the best peakfile for this chunksize doesn't have the
  255. * peaks we need. Perhaps it's still being constructed,
  256. * try the next best, then give up. */
  257. if ( ! _peakfile.open( _clip->name(), chunksize >> 1, _clip->channels() ) )
  258. return 0;
  259. }
  260. return _peakfile.read_peaks( peaks, s, npeaks, chunksize );
  261. // _peakfile.close();
  262. }
  263. int
  264. Peaks::read_source_peaks ( Peak *peaks, int npeaks, nframes_t chunksize ) const
  265. {
  266. int channels = _clip->channels();
  267. sample_t *fbuf = new sample_t[ chunksize * channels ];
  268. size_t len;
  269. int i;
  270. for ( i = 0; i < npeaks; ++i )
  271. {
  272. /* read in a buffer */
  273. len = _clip->read( fbuf, -1, chunksize );
  274. Peak *pk = peaks + (i * channels);
  275. /* get the peak for each channel */
  276. for ( int j = 0; j < channels; ++j )
  277. {
  278. Peak &p = pk[ j ];
  279. p.min = 0;
  280. p.max = 0;
  281. for ( nframes_t k = j; k < len * channels; k += channels )
  282. {
  283. if ( fbuf[ k ] > p.max )
  284. p.max = fbuf[ k ];
  285. if ( fbuf[ k ] < p.min )
  286. p.min = fbuf[ k ];
  287. }
  288. }
  289. if ( len < (nframes_t)chunksize )
  290. break;
  291. }
  292. delete[] fbuf;
  293. return i;
  294. }
  295. int
  296. Peaks::read_source_peaks ( Peak *peaks, nframes_t s, int npeaks, nframes_t chunksize ) const
  297. {
  298. // _clip->open();
  299. _clip->seek( s );
  300. int i = read_source_peaks( peaks, npeaks, chunksize );
  301. // _clip->close();
  302. return i;
  303. }
  304. int
  305. Peaks::read_peaks ( nframes_t s, nframes_t e, int npeaks, nframes_t chunksize ) const
  306. {
  307. // printf( "reading peaks %d @ %d\n", npeaks, chunksize );
  308. if ( _peakbuf.size < (nframes_t)( npeaks * _clip->channels() ) )
  309. {
  310. _peakbuf.size = npeaks * _clip->channels();
  311. // printf( "reallocating peak buffer %li\n", _peakbuf.size );
  312. _peakbuf.buf = (peakdata*)realloc( _peakbuf.buf, sizeof( peakdata ) + (_peakbuf.size * sizeof( Peak )) );
  313. }
  314. _peakbuf.offset = s;
  315. _peakbuf.buf->chunksize = chunksize;
  316. /* FIXME: compart to (minimum) peakfile chunk size */
  317. if ( chunksize < 256 )
  318. _peakbuf.len = read_source_peaks( _peakbuf.buf->data, s, npeaks, chunksize );
  319. else
  320. _peakbuf.len = read_peakfile_peaks( _peakbuf.buf->data, s, npeaks, chunksize );
  321. return _peakbuf.len;
  322. }
  323. /* FIXME: what purpose does this serve now? */
  324. bool
  325. Peaks::open ( void )
  326. {
  327. /* const char *filename = _clip->name(); */
  328. /* /\* FIXME: determine this based on zoom level *\/ */
  329. /* const nframes_t chunksize = 256; */
  330. /* /\* if ( ! current( chunksize ) ) *\/ */
  331. /* /\* /\\* Build peaks asyncronously *\\/ *\/ */
  332. /* /\* if ( ! fork() ) *\/ */
  333. /* /\* exit( make_peaks( chunksize ) ); *\/ */
  334. /* return true; */
  335. }
  336. /** returns false if peak file for /filename/ is out of date */
  337. bool
  338. Peaks::current ( nframes_t chunksize ) const
  339. {
  340. int sfd, pfd;
  341. if ( ( sfd = ::open( _clip->name(), O_RDONLY ) ) < 0 )
  342. return true;
  343. if ( ( pfd = ::open( peakname( _clip->name(), chunksize ), O_RDONLY ) ) < 0 )
  344. return false;
  345. struct stat sst, pst;
  346. fstat( sfd, &sst );
  347. fstat( pfd, &pst );
  348. close( sfd );
  349. close( pfd );
  350. return sst.st_mtime <= pst.st_mtime;
  351. }
  352. /** build peaks file at /chunksize/. If higher-resolution peaks
  353. already exist, downsample those rather than building from
  354. scratch */
  355. bool
  356. Peaks::make_peaks ( void ) const
  357. {
  358. const char *filename = _clip->name();
  359. _clip->seek( 0 );
  360. FILE *fp[ cache_levels ];
  361. Peak buf[ _clip->channels() ];
  362. if ( ! ( fp[ 0 ] = fopen( peakname( filename, cache_minimum ), "w+" ) ) )
  363. return false;
  364. DMESSAGE( "building level 1 peak cache" );
  365. /* build first level from source */
  366. size_t len;
  367. do {
  368. len = read_source_peaks( buf, 1, cache_minimum );
  369. fwrite( buf, sizeof( buf ), len, fp[ 0 ] );
  370. }
  371. while ( len );
  372. /* now build the remaining peak levels, each based on the
  373. * preceding level */
  374. nframes_t cs = cache_minimum << cache_step;
  375. for ( int i = 1; i < cache_levels; ++i, cs <<= cache_step )
  376. {
  377. DMESSAGE( "building level %d peak cache", i + 1 );
  378. Peakfile pf;
  379. if ( ! ( fp[ i ] = fopen( peakname( filename, cs ), "w+" ) ) )
  380. {
  381. DWARNING( "could not open peakfile for writing" );
  382. return false;
  383. }
  384. /* open the peakfile for the previous cache level */
  385. pf.open( fp[ i - 1 ], _clip->channels(), cs >> cache_step );
  386. size_t len;
  387. nframes_t s = 0;
  388. do {
  389. len = pf.read_peaks( buf, s, 1, cs );
  390. s += cs;
  391. fwrite( buf, sizeof( buf ), len, fp[ i ] );
  392. }
  393. while ( len );
  394. pf.leave_open();
  395. }
  396. /* all done */
  397. for ( int i = cache_levels; i--; )
  398. fclose( fp[ i ] );
  399. return true;
  400. }
  401. /** return normalization factor for a single peak, assuming the peak
  402. * represents a downsampling of the entire range to be normalized. */
  403. float
  404. Peak::normalization_factor( void ) const
  405. {
  406. float s;
  407. s = 1.0f / fabs( this->max );
  408. if ( s * this->min < -1.0 )
  409. s = 1.0f / fabs( this->min );
  410. return s;
  411. }
  412. /* wrapper for peak writer */
  413. void
  414. Peaks::prepare_for_writing ( void )
  415. {
  416. assert( ! _peak_writer );
  417. _peak_writer = new Peak_Writer( _clip->name(), cache_minimum, _clip->channels() );
  418. }
  419. void
  420. Peaks::write ( sample_t *buf, nframes_t nframes )
  421. {
  422. _peak_writer->write( buf, nframes );
  423. }
  424. /* The Peak_Writer is for streaming peaks from audio buffers to disk
  425. * while capturing. It works by accumulating a peak value across
  426. * write() calls. */
  427. Peak_Writer::Peak_Writer ( const char *filename, nframes_t chunksize, int channels )
  428. {
  429. _channels = channels;
  430. _chunksize = chunksize;
  431. _index = 0;
  432. _peak = new Peak[ channels ];
  433. memset( _peak, 0, sizeof( Peak ) * channels );
  434. if ( ! ( _fp = fopen( peakname( filename, chunksize ), "w" ) ) )
  435. /* error! */;
  436. }
  437. Peak_Writer::~Peak_Writer ( )
  438. {
  439. fclose( _fp );
  440. delete[] _peak;
  441. }
  442. /** append peaks for samples in /buf/ to peakfile */
  443. void
  444. Peak_Writer::write ( sample_t *buf, nframes_t nframes )
  445. {
  446. for ( ; nframes--; ++_index, buf += _channels )
  447. {
  448. for ( int j = 0; j < _channels; ++j )
  449. {
  450. Peak *p = _peak + j;
  451. if ( *buf > p->max )
  452. p->max = *buf;
  453. if ( *buf < p->min )
  454. p->min = *buf;
  455. }
  456. if ( _index == _chunksize - 1 )
  457. {
  458. fwrite( _peak, sizeof( Peak ), _channels, _fp );
  459. memset( _peak, 0, sizeof( Peak ) * _channels );
  460. _index = 0;
  461. }
  462. }
  463. }