| @@ -27,6 +27,18 @@ Audio_File::~Audio_File ( ) | |||||
| _open_files[ std::string( _filename ) ] = NULL; | _open_files[ std::string( _filename ) ] = NULL; | ||||
| } | } | ||||
| void | |||||
| Audio_File::all_supported_formats ( std::list <const char *> &formats ) | |||||
| { | |||||
| const format_desc *fd; | |||||
| fd = Audio_File_SF::supported_formats; | |||||
| for ( ; fd->name; ++fd ) | |||||
| formats.push_back( fd->name ); | |||||
| } | |||||
| /** attmpet to open any supported filetype */ | /** attmpet to open any supported filetype */ | ||||
| Audio_File * | Audio_File * | ||||
| Audio_File::from_file ( const char * filename ) | Audio_File::from_file ( const char * filename ) | ||||
| @@ -25,9 +25,9 @@ | |||||
| #include "types.h" | #include "types.h" | ||||
| #include "Peaks.H" | #include "Peaks.H" | ||||
| #include <string> | #include <string> | ||||
| #include <map> | #include <map> | ||||
| #include <list> | |||||
| class Peak_Writer; | class Peak_Writer; | ||||
| @@ -37,6 +37,12 @@ class Audio_File | |||||
| protected: | protected: | ||||
| struct format_desc | |||||
| { | |||||
| const char *name; | |||||
| const char *extension; | |||||
| unsigned long id; | |||||
| }; | |||||
| const char *_filename; | const char *_filename; | ||||
| nframes_t _length; /* length of file in samples */ | nframes_t _length; /* length of file in samples */ | ||||
| @@ -47,6 +53,17 @@ protected: | |||||
| Peak_Writer *_peak_writer; | Peak_Writer *_peak_writer; | ||||
| static const format_desc * | |||||
| find_format ( const format_desc *fd, const char *name ) | |||||
| { | |||||
| for ( ; fd->name; ++fd ) | |||||
| if ( ! strcmp( fd->name, name ) ) | |||||
| return fd; | |||||
| return NULL; | |||||
| } | |||||
| public: | public: | ||||
| Audio_File ( ) | Audio_File ( ) | ||||
| @@ -57,6 +74,8 @@ public: | |||||
| virtual ~Audio_File ( ); | virtual ~Audio_File ( ); | ||||
| static void all_supported_formats ( std::list <const char *> &formats ); | |||||
| static Audio_File *from_file ( const char *filename ); | static Audio_File *from_file ( const char *filename ); | ||||
| Peaks const * peaks ( ) { return _peaks; } | Peaks const * peaks ( ) { return _peaks; } | ||||
| @@ -29,6 +29,22 @@ | |||||
| #include "Peaks.H" | #include "Peaks.H" | ||||
| // #define HAS_SF_FORMAT_VORBIS | |||||
| const Audio_File::format_desc Audio_File_SF::supported_formats[] = | |||||
| { | |||||
| { "Wav 24", "wav", SF_FORMAT_WAV | SF_FORMAT_PCM_24 | SF_ENDIAN_FILE }, | |||||
| { "Wav 16", "wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_FILE }, | |||||
| { "Wav f32", "wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT | SF_ENDIAN_FILE }, | |||||
| { "Au 24", "au", SF_FORMAT_AU | SF_FORMAT_PCM_24 | SF_ENDIAN_FILE }, | |||||
| { "Au 16", "au", SF_FORMAT_AU | SF_FORMAT_PCM_16 | SF_ENDIAN_FILE }, | |||||
| { "FLAC", "flac", SF_FORMAT_FLAC | SF_FORMAT_PCM_24 }, | |||||
| #ifdef HAS_SF_FORMAT_VORBIS | |||||
| { "Ogg Vorbis", "ogg", SF_FORMAT_OGG | SF_FORMAT_VORBIS | SF_FORMAT_PCM_16 }, | |||||
| #endif | |||||
| { 0, 0 } | |||||
| }; | |||||
| Audio_File_SF * | Audio_File_SF * | ||||
| Audio_File_SF::from_file ( const char *filename ) | Audio_File_SF::from_file ( const char *filename ) | ||||
| { | { | ||||
| @@ -78,21 +94,29 @@ Audio_File_SF::create ( const char *filename, nframes_t samplerate, int channels | |||||
| memset( &si, 0, sizeof( si ) ); | memset( &si, 0, sizeof( si ) ); | ||||
| const Audio_File::format_desc *fd = Audio_File::find_format( Audio_File_SF::supported_formats, format ); | |||||
| if ( ! fd ) | |||||
| return (Audio_File_SF *)1; | |||||
| si.samplerate = samplerate; | si.samplerate = samplerate; | ||||
| si.channels = channels; | si.channels = channels; | ||||
| si.format = fd->id; | |||||
| /* FIXME: bogus */ | |||||
| si.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24 | SF_ENDIAN_CPU; | |||||
| char *name; | |||||
| asprintf( &name, "%s.%s", filename, fd->extension ); | |||||
| if ( ! ( out = sf_open( filename, SFM_RDWR, &si ) ) ) | |||||
| // if ( ! ( out = sf_open( name, SFM_RDWR, &si ) ) ) | |||||
| if ( ! ( out = sf_open( name, SFM_WRITE, &si ) ) ) | |||||
| { | { | ||||
| printf( "couldn't create soundfile.\n" ); | printf( "couldn't create soundfile.\n" ); | ||||
| free( name ); | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| Audio_File_SF *c = new Audio_File_SF; | Audio_File_SF *c = new Audio_File_SF; | ||||
| c->_filename = strdup( filename ); | |||||
| c->_filename = name; | |||||
| c->_length = 0; | c->_length = 0; | ||||
| c->_samplerate = samplerate; | c->_samplerate = samplerate; | ||||
| c->_channels = channels; | c->_channels = channels; | ||||
| @@ -33,6 +33,8 @@ class Audio_File_SF : public Audio_File | |||||
| public: | public: | ||||
| static const Audio_File::format_desc supported_formats[]; | |||||
| static Audio_File_SF *from_file ( const char *filename ); | static Audio_File_SF *from_file ( const char *filename ); | ||||
| static Audio_File_SF *create ( const char *filename, nframes_t samplerate, int channels, const char *format ); | static Audio_File_SF *create ( const char *filename, nframes_t samplerate, int channels, const char *format ); | ||||
| @@ -17,6 +17,11 @@ decl {\#include "Loggable.H"} {} | |||||
| decl {\#include "Clock.H"} {public | decl {\#include "Clock.H"} {public | ||||
| } | } | ||||
| decl {\#include "Track.H" // for capture_format} {selected | |||||
| } | |||||
| decl {\#include "Audio_File.H" // for supported formats} {} | |||||
| decl {\#include "Waveform.H" // for options} {} | decl {\#include "Waveform.H" // for options} {} | ||||
| decl {\#include "Control_Sequence.H" // for options} {} | decl {\#include "Control_Sequence.H" // for options} {} | ||||
| @@ -36,6 +41,32 @@ class TLE {open | |||||
| } { | } { | ||||
| code {return m->menu()[ m->value() ].flags & FL_MENU_VALUE;} {} | code {return m->menu()[ m->value() ].flags & FL_MENU_VALUE;} {} | ||||
| } | } | ||||
| Function {save()} {open | |||||
| } { | |||||
| code {const char options_filename[] = "options"; | |||||
| const char state_filename[] = "state"; | |||||
| // save options | |||||
| char *path; | |||||
| asprintf( &path, "%s/%s", user_config_dir, options_filename ); | |||||
| ((Fl_Menu_Settings*)menubar)->dump( options_menu, path ); | |||||
| free( path ); | |||||
| // save unjournaled state | |||||
| // Loggable::save_unjournaled( state_filename );} {} | |||||
| } | |||||
| Function {capture_format_cb( Fl_Widget *w, void *v )} {open private return_type {static void} | |||||
| } { | |||||
| code {((TLE*)v)->capture_format_cb();} {} | |||||
| } | |||||
| Function {capture_format_cb()} {open private return_type void | |||||
| } { | |||||
| code {Fl_Menu_ *o = menubar; | |||||
| Track::capture_format = o->menu()[ o->value() ].label();} {} | |||||
| } | |||||
| Function {TLE()} {open | Function {TLE()} {open | ||||
| } { | } { | ||||
| code {make_window(); | code {make_window(); | ||||
| @@ -52,7 +83,22 @@ Fl::add_timeout( STATUS_UPDATE_FREQ, update_cb, this ); | |||||
| char *path; | char *path; | ||||
| asprintf( &path, "%s/options", user_config_dir ); | asprintf( &path, "%s/options", user_config_dir ); | ||||
| ((Fl_Menu_Settings*)menubar)->load( options_menu, path ); | ((Fl_Menu_Settings*)menubar)->load( options_menu, path ); | ||||
| free( path );} {} | |||||
| free( path ); | |||||
| std::list <const char *> formats; | |||||
| Audio_File::all_supported_formats( formats ); | |||||
| for ( std::list <const char *>::const_iterator f = formats.begin(); f != formats.end(); ++f ) | |||||
| { | |||||
| // capture_format_menu->add( *f, FL_MENU_RADIO, 0, 0, 0 ); | |||||
| //; | |||||
| char pat[256]; | |||||
| snprintf( pat, sizeof( pat ), "Timeline/Capture Format/%s", *f ); | |||||
| menubar->add( pat, 0, &TLE::capture_format_cb, this, FL_MENU_RADIO ); | |||||
| }} {} | |||||
| } | } | ||||
| Function {make_window()} {open | Function {make_window()} {open | ||||
| } { | } { | ||||
| @@ -60,8 +106,7 @@ free( path );} {} | |||||
| label {Non-DAW - Timeline} open | label {Non-DAW - Timeline} open | ||||
| xywh {522 141 1024 768} type Double resizable xclass {Non-DAW} visible | xywh {522 141 1024 768} type Double resizable xclass {Non-DAW} visible | ||||
| } { | } { | ||||
| Fl_Menu_Bar menubar { | |||||
| label {capture:\\nfoo} open | |||||
| Fl_Menu_Bar menubar {open | |||||
| xywh {0 0 1024 25} | xywh {0 0 1024 25} | ||||
| } { | } { | ||||
| Submenu {} { | Submenu {} { | ||||
| @@ -101,10 +146,7 @@ Loggable::compact();} | |||||
| } | } | ||||
| MenuItem {} { | MenuItem {} { | ||||
| label {&Quit} | label {&Quit} | ||||
| callback {char *path; | |||||
| asprintf( &path, "%s/options", user_config_dir ); | |||||
| ((Fl_Menu_Settings*)menubar)->dump( options_menu, path ); | |||||
| free( path ); | |||||
| callback {save(); | |||||
| exit( 0 );} | exit( 0 );} | ||||
| xywh {40 40 40 25} shortcut 0x40071 | xywh {40 40 40 25} shortcut 0x40071 | ||||
| @@ -120,7 +162,7 @@ exit( 0 );} | |||||
| } | } | ||||
| MenuItem {} { | MenuItem {} { | ||||
| label Undo | label Undo | ||||
| callback {Loggable::undo();} selected | |||||
| callback {Loggable::undo();} | |||||
| xywh {0 0 40 25} shortcut 0x4007a | xywh {0 0 40 25} shortcut 0x4007a | ||||
| } | } | ||||
| } | } | ||||
| @@ -213,6 +255,10 @@ exit( 0 );} | |||||
| xywh {20 20 40 25} type Radio | xywh {20 20 40 25} type Radio | ||||
| } | } | ||||
| } | } | ||||
| Submenu {} { | |||||
| label {Capture Format} open | |||||
| xywh {0 0 74 25} | |||||
| } {} | |||||
| } | } | ||||
| Submenu options_menu { | Submenu options_menu { | ||||
| label {&Options} | label {&Options} | ||||
| @@ -446,6 +492,3 @@ update_progress( cpu_load_progress, clp, engine->cpu_load() );} {} | |||||
| ((TLE*)v)->update_status();} {} | ((TLE*)v)->update_status();} {} | ||||
| } | } | ||||
| } | } | ||||
| Function {make_window()} {open | |||||
| } {} | |||||
| @@ -32,6 +32,8 @@ | |||||
| int Track::_soloing = 0; | int Track::_soloing = 0; | ||||
| const char *Track::capture_format = "Wav 24"; | |||||
| void | void | ||||
| Track::cb_input_field ( Fl_Widget *w, void *v ) | Track::cb_input_field ( Fl_Widget *w, void *v ) | ||||
| { | { | ||||
| @@ -639,10 +641,10 @@ Track::record ( nframes_t frame ) | |||||
| char pat[256]; | char pat[256]; | ||||
| snprintf( pat, sizeof( pat ), "%s-%llu.wav", name(), uuid() ); | |||||
| snprintf( pat, sizeof( pat ), "%s-%llu", name(), uuid() ); | |||||
| /* FIXME: hack */ | /* FIXME: hack */ | ||||
| Audio_File *af = Audio_File_SF::create( pat, 48000, input.size(), "Wav/24" ); | |||||
| Audio_File *af = Audio_File_SF::create( pat, 48000, input.size(), Track::capture_format ); | |||||
| _capture = new Region( af, track(), frame ); | _capture = new Region( af, track(), frame ); | ||||
| @@ -56,6 +56,8 @@ public: | |||||
| static bool soloing ( void ) { return _soloing; } | static bool soloing ( void ) { return _soloing; } | ||||
| static const char *capture_format; | |||||
| private: | private: | ||||
| static int _soloing; | static int _soloing; | ||||