Update NTK.
[nondaw.git] / timeline / src / Engine / Audio_File.C
blobeeea756d05365dc250a31982c20794d4ecc2dcd0
2 /*******************************************************************************/
3 /* Copyright (C) 2008 Jonathan Moore Liles                                     */
4 /*                                                                             */
5 /* This program is free software; you can redistribute it and/or modify it     */
6 /* under the terms of the GNU General Public License as published by the       */
7 /* Free Software Foundation; either version 2 of the License, or (at your      */
8 /* option) any later version.                                                  */
9 /*                                                                             */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       */
12 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   */
13 /* more details.                                                               */
14 /*                                                                             */
15 /* You should have received a copy of the GNU General Public License along     */
16 /* with This program; see the file COPYING.  If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18 /*******************************************************************************/
20 #include "Audio_File.H"
21 #include "Audio_File_SF.H"
22 #include "Audio_File_Dummy.H"
24 #include "const.h"
25 #include "debug.h"
26 #include "Block_Timer.H"
28 #include <string.h>
30 std::map <std::string, Audio_File*> Audio_File::_open_files;
32 Audio_File::~Audio_File ( )
34     DMESSAGE( "Freeing Audio_File object for \"%s\"", _filename );
36     _open_files[ std::string( _filename ) ] = NULL;
38     if ( _filename )
39         free( _filename );
41     if ( _path )
42         free( _path );
45 const Audio_File::format_desc *
46 Audio_File::find_format ( const format_desc *fd, const char *name )
48     for ( ; fd->name; ++fd )
49         if ( ! strcmp( fd->name, name ) )
50             return fd;
52     return NULL;
55 void
56 Audio_File::all_supported_formats ( std::list <const char *> &formats )
58     const format_desc *fd;
60     fd = Audio_File_SF::supported_formats;
62     for ( ; fd->name; ++fd )
63         formats.push_back( fd->name );
66 static bool
67 is_absolute ( const char *name )
69     return *name == '/';
72 /** return pointer to /name/ corrected for relative path. */
73 char *Audio_File::path ( const char *name )
75     char *path = 0;
77     if ( is_absolute( name ) )
78         path = strdup( name );
79     else
80         asprintf( &path, "sources/%s", name );
82     return path;
85 const char *
86 Audio_File::filename ( void ) const
88     return _path;
91 /** attempt to open any supported filetype */
92 Audio_File *
93 Audio_File::from_file ( const char * filename )
95     Block_Timer timer( "Opened audio file" );
97     Audio_File *a;
99     if ( ( a = _open_files[ std::string( filename ) ] ) )
100     {
101         ++a->_refs;
103         return a;
104     }
106     if ( ( a = Audio_File_SF::from_file( filename ) ) )
107         goto done;
109 // TODO: other formats
111     DWARNING( "creating dummy source for \"%s\"", filename );
113     /* FIXME: wrong place for this? */
114     if ( ( a = Audio_File_Dummy::from_file( filename ) ) )
115         goto done;
117     return NULL;
119 done:
121     ASSERT( ! _open_files[ std::string( filename ) ], "Programming errror" );
123     _open_files[ std::string( filename ) ] = a;
125     a->_refs = 1;
127     return a;
130 Audio_File *
131 Audio_File::duplicate ( void )
133     ++_refs;
134     return this;
137 /** release the resources assoicated with this audio file if no other
138  * references to it exist */
139 void
140 Audio_File::release ( void )
142     if ( --_refs == 0 )
143         delete this;
147 bool
148 Audio_File::read_peaks( float fpp, nframes_t start, nframes_t end, int *peaks, Peak **pbuf, int *channels )
150     *peaks = 0;
151     *channels = 0;
152     *pbuf = NULL;
153     
154     if ( dummy() )
155         return false;
156     else
157     {
158         *peaks = _peaks.fill_buffer( fpp, start, end );
160         *channels = this->channels();
162         *pbuf = _peaks.peakbuf();
164         return true;
165     }