@@ -27,6 +27,18 @@ Audio_File::~Audio_File ( ) | |||
_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 */ | |||
Audio_File * | |||
Audio_File::from_file ( const char * filename ) | |||
@@ -25,9 +25,9 @@ | |||
#include "types.h" | |||
#include "Peaks.H" | |||
#include <string> | |||
#include <map> | |||
#include <list> | |||
class Peak_Writer; | |||
@@ -37,6 +37,12 @@ class Audio_File | |||
protected: | |||
struct format_desc | |||
{ | |||
const char *name; | |||
const char *extension; | |||
unsigned long id; | |||
}; | |||
const char *_filename; | |||
nframes_t _length; /* length of file in samples */ | |||
@@ -47,6 +53,17 @@ protected: | |||
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: | |||
Audio_File ( ) | |||
@@ -57,6 +74,8 @@ public: | |||
virtual ~Audio_File ( ); | |||
static void all_supported_formats ( std::list <const char *> &formats ); | |||
static Audio_File *from_file ( const char *filename ); | |||
Peaks const * peaks ( ) { return _peaks; } | |||
@@ -29,6 +29,22 @@ | |||
#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::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 ) ); | |||
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.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" ); | |||
free( name ); | |||
return NULL; | |||
} | |||
Audio_File_SF *c = new Audio_File_SF; | |||
c->_filename = strdup( filename ); | |||
c->_filename = name; | |||
c->_length = 0; | |||
c->_samplerate = samplerate; | |||
c->_channels = channels; | |||
@@ -33,6 +33,8 @@ class Audio_File_SF : public Audio_File | |||
public: | |||
static const Audio_File::format_desc supported_formats[]; | |||
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 ); | |||
@@ -17,6 +17,11 @@ decl {\#include "Loggable.H"} {} | |||
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 "Control_Sequence.H" // for options} {} | |||
@@ -36,6 +41,32 @@ class TLE {open | |||
} { | |||
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 | |||
} { | |||
code {make_window(); | |||
@@ -52,7 +83,22 @@ Fl::add_timeout( STATUS_UPDATE_FREQ, update_cb, this ); | |||
char *path; | |||
asprintf( &path, "%s/options", user_config_dir ); | |||
((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 | |||
} { | |||
@@ -60,8 +106,7 @@ free( path );} {} | |||
label {Non-DAW - Timeline} open | |||
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} | |||
} { | |||
Submenu {} { | |||
@@ -101,10 +146,7 @@ Loggable::compact();} | |||
} | |||
MenuItem {} { | |||
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 );} | |||
xywh {40 40 40 25} shortcut 0x40071 | |||
@@ -120,7 +162,7 @@ exit( 0 );} | |||
} | |||
MenuItem {} { | |||
label Undo | |||
callback {Loggable::undo();} selected | |||
callback {Loggable::undo();} | |||
xywh {0 0 40 25} shortcut 0x4007a | |||
} | |||
} | |||
@@ -213,6 +255,10 @@ exit( 0 );} | |||
xywh {20 20 40 25} type Radio | |||
} | |||
} | |||
Submenu {} { | |||
label {Capture Format} open | |||
xywh {0 0 74 25} | |||
} {} | |||
} | |||
Submenu options_menu { | |||
label {&Options} | |||
@@ -446,6 +492,3 @@ update_progress( cpu_load_progress, clp, engine->cpu_load() );} {} | |||
((TLE*)v)->update_status();} {} | |||
} | |||
} | |||
Function {make_window()} {open | |||
} {} |
@@ -32,6 +32,8 @@ | |||
int Track::_soloing = 0; | |||
const char *Track::capture_format = "Wav 24"; | |||
void | |||
Track::cb_input_field ( Fl_Widget *w, void *v ) | |||
{ | |||
@@ -639,10 +641,10 @@ Track::record ( nframes_t frame ) | |||
char pat[256]; | |||
snprintf( pat, sizeof( pat ), "%s-%llu.wav", name(), uuid() ); | |||
snprintf( pat, sizeof( pat ), "%s-%llu", name(), uuid() ); | |||
/* 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 ); | |||
@@ -56,6 +56,8 @@ public: | |||
static bool soloing ( void ) { return _soloing; } | |||
static const char *capture_format; | |||
private: | |||
static int _soloing; | |||