2 Kjetil Matheussen, 2005-2010.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <semaphore.h>
37 #include <sys/sysinfo.h>
38 #include <sys/types.h>
43 #include <sys/resource.h>
45 #include <jack/jack.h>
48 #include <lame/lame.h>
51 #include "vringbuffer.h"
53 extern char **environ
;
55 #define JC_MAX(a,b) (((a)>(b))?(a):(b))
56 #define JC_MIN(a,b) (((a)<(b))?(a):(b))
59 #define ALIGN_UP(value,alignment) (((uintptr_t)value + alignment - 1) & -alignment)
60 #define ALIGN_UP_DOUBLE(p) ALIGN_UP(p,sizeof(double)) // Using double because double should always be very large.
63 #define OPTARGS_CHECK_GET(wrong,right) lokke==argc-1?(fprintf(stderr,"Must supply argument for '%s'\n",argv[lokke]),exit(-4),wrong):right
65 #define OPTARGS_BEGIN(das_usage) {int lokke;const char *usage=das_usage;for(lokke=1;lokke<argc;lokke++){char *a=argv[lokke];if(!strcmp("--help",a)||!strcmp("-h",a)){fprintf(stderr,usage);exit(0);
66 #define OPTARG(name,name2) }}else if(!strcmp(name,a)||!strcmp(name2,a)){{
67 #define OPTARG_GETINT() OPTARGS_CHECK_GET(0,atoi(argv[++lokke]))
68 //int optargs_inttemp;
69 //#define OPTARG_GETINT() OPTARGS_CHECK_GET(0,(optargs_inttemp=strtol(argv[++lokke],(char**)NULL,10),errno!=0?(perror("strtol"),0):optargs_inttemp))
70 #define OPTARG_GETFLOAT() OPTARGS_CHECK_GET(0.0f,atof(argv[++lokke]))
71 #define OPTARG_GETSTRING() OPTARGS_CHECK_GET("",argv[++lokke])
72 #define OPTARG_LAST() }}else if(lokke==argc-1 && argv[lokke][0]!='-'){lokke--;{
73 #define OPTARGS_ELSE() }else if(1){
74 #define OPTARGS_END }else{fprintf(stderr,usage);exit(-1);}}}
78 /* Arguments and their default values */
79 #define DEFAULT_MIN_BUFFER_TIME 4
80 #define DEFAULT_MIN_MP3_BUFFER_TIME 8
81 static float min_buffer_time
=-1.0f
;
82 static float max_buffer_time
=40.0f
;
83 static jack_client_t
*client
=NULL
;
84 #define DEFAULT_NUM_CHANNELS 2
85 static int channels
=-1;
86 static int bitdepth
=0;
87 static char *base_filename
=NULL
;
88 static char *filename
=NULL
;
89 static bool use_vu
=true;
90 static bool use_meterbridge
=false;
91 static bool show_bufferusage
=true;
92 static char *meterbridge_type
="vu";
93 static char *meterbridge_reference
="0";
94 //static const int vu_len=56;
96 static int vu_dB
=true;
97 static float vu_bias
=1.0f
;
98 static int leading_zeros
=1;
99 static int64_t num_frames_recorded
=0;
100 static int64_t num_frames_to_record
=0;
101 static bool wait_for_keyboard
=true;
102 static double recording_time
=0.0;
103 static const int disk_error_stop
=0;
104 static int disk_errors
=0;
105 static bool soundfile_format_is_set
=false;
106 static char *soundfile_format
="wav";
107 static char *soundfile_format_one_or_two
="wav";
108 #define ONE_OR_TWO_CHANNELS_FORMAT SF_FORMAT_WAV
109 static char *soundfile_format_multi
="wavex";
110 #define MORE_THAN_TWO_CHANNELS_FORMAT SF_FORMAT_WAVEX
111 static bool silent
=false;
112 static bool verbose
=false;
113 static bool write_to_stdout
=false;
114 static bool write_to_mp3
= false;
115 static int das_lame_quality
= 2; // 0 best, 9 worst.
116 static int das_lame_bitrate
= -1;
117 static bool use_jack_transport
= false;
121 static jack_port_t
**ports
;
122 static jack_port_t
**ports_meterbridge
=NULL
;
123 typedef jack_default_audio_sample_t sample_t
;
124 static float jack_samplerate
;
125 static bool jack_has_been_shut_down
=false;
127 static int64_t unreported_overruns
=0;
128 static int total_overruns
=0;
133 static lame_global_flags
*lame
;
136 static bool disk_thread_has_high_priority
=false;
140 static pthread_t helper_thread
={0};
141 static float *vu_vals
=NULL
;
142 static int *vu_times
=NULL
;
143 static int *vu_peaks
=NULL
;
144 static float *vu_peakvals
=NULL
;
145 static void print_message(const char *fmt
, ...);
147 /* Synchronization between jack process thread and disk thread. */
148 static volatile int is_initialized
=0; // This $@#$@#$ variable is needed because jack ports must be initialized _after_ (???) the client is activated. (stupid jack)
149 static volatile int is_running
=1; // Mostly used to stop recording as early as possible.
153 // Set once only. Never changes value after that, even if jack buffer size changes.
154 static int block_size
;
156 static bool buffer_interleaved
= true;
159 typedef struct buffer_t
{
165 //static pid_t mainpid;
167 static buffer_t
*current_buffer
;
169 /* Jack connecting thread. */
170 static pthread_t connect_thread
={0} ;
173 // das stop semaphore
174 static sem_t stop_sem
;
180 /////////////////////////////////////////////////////////////////////
181 //////////////////////// VARIOUS ////////////////////////////////////
182 /////////////////////////////////////////////////////////////////////
185 void get_free_mem(void){
186 struct sysinfo sys_info
;
188 if(sysinfo(&sys_info
) != 0)
191 printf("Total Ram ----- %uk\tFree Ram ------ %uk\n", sys_info
.totalram
193 sys_info
.freeram
/ 1024);
197 static void verbose_print(const char *fmt
, ...){
201 vfprintf(stderr
,fmt
,argp
);
206 static void* my_calloc(size_t size1
,size_t size2
){
207 size_t size
=size1
*size2
;
208 void* ret
=malloc(size
);
210 fprintf(stderr
,"\nOut of memory. Try a smaller buffer.\n");
217 static bool set_high_priority(void){
218 static bool shown_warning
= false;
221 while(setpriority(PRIO_PROCESS
,0,prio
)==-1){
227 if(prio
==0 && shown_warning
==false){
228 print_message("Warning. Could not set higher priority for a SCHED_FIFO process using setpriority().\n");
239 static int echo_turned_on
=true;
240 static struct termios current
;
241 static struct termios initial
;
243 static void turn_off_echo(void){
244 tcgetattr( STDIN_FILENO
, &initial
);
246 current
.c_lflag
&= ~ECHO
; // added
247 tcsetattr( STDIN_FILENO
, TCSANOW
, ¤t
);
249 echo_turned_on
=false;
252 static void turn_on_echo(void){
253 if(echo_turned_on
==true)
255 tcsetattr( STDIN_FILENO
, TCSANOW
, &initial
);
260 /////////////////////////////////////////////////////////////////////
261 //////////////////////// BUFFERS ////////////////////////////////////
262 /////////////////////////////////////////////////////////////////////
265 static vringbuffer_t
*vringbuffer
;
267 //static sample_t **buffers=NULL;
268 static sample_t
*empty_buffer
;
270 static int buffer_size_in_bytes
;
272 // block size in bytes = jack block size (1 channel) * sizeof(float)
273 // buffer size in bytes = block size in bytes * num_channels
276 static int seconds_to_frames(float seconds
){
277 return (int)(seconds
*jack_samplerate
);
281 static float frames_to_seconds(int frames){
282 return ((float)frames)/jack_samplerate;
287 static int seconds_to_blocks(float seconds
){
288 return (int)ceilf((seconds
*jack_samplerate
/(float)block_size
));
291 // same return value as seconds_to_blocks
292 static int seconds_to_buffers(float seconds
){
293 return seconds_to_blocks(seconds
);
298 static int block_time_in_microseconds(void){
299 return (int)(((double)block_size
*1000000.0)/(double)jack_samplerate
);
303 static float blocks_to_seconds(int blocks
){
304 return (float)blocks
*(float)block_size
/jack_samplerate
;
307 // same return value as blocks_to_seconds
308 static float buffers_to_seconds(int buffers
){
309 return blocks_to_seconds(buffers
);
313 static int autoincrease_callback(vringbuffer_t
*vrb
, bool first_call
, int reading_size
, int writing_size
){
321 static jack_transport_state_t prev_state
=-1;
323 jack_transport_state_t state
=jack_transport_query(client
,&pos
);
324 if(state
!=prev_state
){
325 print_message("frame: %d\n",pos
.frame
);
331 if(buffers_to_seconds(writing_size
) < min_buffer_time
)
332 return 2; // autoincrease_callback is called approx. at every block. So it should not be necessary to return a value higher than 2. Returning a very low number might also theoretically put a lower constant strain on the memory bus, thus theoretically lower the chance of xruns.
337 static void buffers_init(){
338 verbose_print("bufinit1. sizeof(long): %u, sizeof(float): %u, sizeof(double):%u, sizeof(int):%u, sizeof(void*):%u\n",sizeof(long),sizeof(float),sizeof(double),sizeof(int),sizeof(void*));
340 vringbuffer
= vringbuffer_create(JC_MAX(4,seconds_to_buffers(min_buffer_time
)),
341 JC_MAX(4,seconds_to_buffers(max_buffer_time
)),
342 buffer_size_in_bytes
);
344 if(vringbuffer
==NULL
){
345 fprintf(stderr
,"Unable to allocate memory for buffers\n");
349 vringbuffer_set_autoincrease_callback(vringbuffer
,autoincrease_callback
,0);
351 current_buffer
= vringbuffer_get_writing(vringbuffer
);
352 empty_buffer
= my_calloc(sizeof(sample_t
),block_size
*channels
);
357 /////////////////////////////////////////////////////////////////////
358 //////////////////////// PORTNAMES //////////////////////////////////
359 /////////////////////////////////////////////////////////////////////
360 static char **cportnames
=NULL
;
361 static int num_cportnames
=0;
363 static int findnumports(char **ports
){
365 while(ports
&& ports
[ret
]!=NULL
)
371 static void portnames_add_defaults(void){
372 if(cportnames
==NULL
){
373 cportnames
=(char **)jack_get_ports(client
,NULL
,NULL
,JackPortIsPhysical
|JackPortIsInput
);
374 num_cportnames
=JC_MAX(DEFAULT_NUM_CHANNELS
,findnumports(cportnames
));
375 if(num_cportnames
==0){
376 fprintf(stderr
,"No physical output ports found in your jack setup. Exiting.\n");
380 channels
=DEFAULT_NUM_CHANNELS
;
383 channels
=num_cportnames
;
386 fprintf(stderr
,"No point recording 0 channels. Exiting.\n");
390 // At this point, the variable "channels" has a known and valid value.
391 vu_vals
=my_calloc(sizeof(float),channels
);
392 vu_times
=my_calloc(sizeof(int),channels
);
393 vu_peaks
=my_calloc(sizeof(int),channels
);
394 vu_peakvals
=my_calloc(sizeof(float),channels
);
396 buffer_size_in_bytes
= ALIGN_UP_DOUBLE(sizeof(buffer_t
) + block_size
*channels
*sizeof(sample_t
));
397 verbose_print("buf_size_in_bytes: %d\n",buffer_size_in_bytes
);
401 static void portnames_add(char *name
){
402 char **new_outportnames
;
405 if(name
[strlen(name
)-1]=='*'){
406 char pattern
[strlen(name
)];
408 sprintf(pattern
,name
);
410 pattern
[strlen(name
)-1]=0;
412 new_outportnames
=(char**)jack_get_ports(client
,pattern
,"",0);
413 //char **new_outportnames=(char**)jack_get_ports(client,"system:capture_1$","",0);
414 add_ch
=findnumports(new_outportnames
);
416 new_outportnames
=my_calloc(1,sizeof(char*));
417 new_outportnames
[0]=name
;
424 cportnames
=realloc(cportnames
,(num_cportnames
+add_ch
)*sizeof(char*));
426 for(ch
=0;ch
<add_ch
;ch
++){
427 cportnames
[num_cportnames
]=new_outportnames
[ch
];
428 //fprintf(stderr,"ch: %d, num_ch: %d, new_outportnames[ch]: %s, %s\n",ch,num_cportnames,new_outportnames[ch],new_outportnames[ch+1]);
433 fprintf(stderr
,"\nWarning, No port(s) with name \"%s\".\n",name
);
436 fprintf(stderr
,"This could lead to using default ports instead.\n");
441 static char **portnames_get_connections(int ch
){
442 if(ch
>=num_cportnames
)
445 jack_port_t
* port
=jack_port_by_name(client
,cportnames
[ch
]);
449 print_message("Error, port with name \"%s\" not found.\n",cportnames
[ch
]);
453 if(jack_port_flags(port
) & JackPortIsInput
){
454 ret
=(char**)jack_port_get_all_connections(client
,port
);
456 ret
=my_calloc(2,sizeof(char*));
457 ret
[0]=cportnames
[ch
];
468 /////////////////////////////////////////////////////////////////////
469 //////////////////////// console meter //////////////////////////////
470 /////////////////////////////////////////////////////////////////////
472 // Note that the name "vu" is used instead of "console meter".
473 // I know (now) it's not a vu at all. :-)
476 // Function iec_scale picked from meterbridge by Steve Harris.
477 static int iec_scale(float db
) {
478 float def
= 0.0f
; /* Meter deflection %age */
482 } else if (db
< -60.0f
) {
483 def
= (db
+ 70.0f
) * 0.25f
;
484 } else if (db
< -50.0f
) {
485 def
= (db
+ 60.0f
) * 0.5f
+ 5.0f
;
486 } else if (db
< -40.0f
) {
487 def
= (db
+ 50.0f
) * 0.75f
+ 7.5;
488 } else if (db
< -30.0f
) {
489 def
= (db
+ 40.0f
) * 1.5f
+ 15.0f
;
490 } else if (db
< -20.0f
) {
491 def
= (db
+ 30.0f
) * 2.0f
+ 30.0f
;
492 } else if (db
< 0.0f
) {
493 def
= (db
+ 20.0f
) * 2.5f
+ 50.0f
;
498 return (int)(def
* 2.0f
);
501 static void print_console_top(void){
506 printf("%c[36m",0x1b);
510 for(lokke
=0;lokke
<vu_len
;lokke
++)
518 static void init_vu(void){
521 for(ch
=0;ch
<channels
;ch
++)
525 static void init_show_bufferusage(void){
530 static void move_cursor_to_top(void){
531 printf("%c[%dA",0x1b,
532 use_vu
&&show_bufferusage
542 // http://www.linuxjournal.com/article/8603
544 static void print_console(bool move_cursor_to_top_doit
,bool force_update
){
552 // Values have not been updated since last time. Return.
553 if(force_update
==false && vu_vals
[0]==-1.0f
)
556 if(move_cursor_to_top_doit
)
557 move_cursor_to_top();
562 printf("%c[36m",0x1b);
564 for(ch
=0;ch
<channels
;ch
++){
566 float val
=vu_vals
[ch
];
571 pos
=iec_scale(20.0f
* log10f(val
* vu_bias
)) * (vu_len
) / 200;
575 if (pos
> vu_peaks
[ch
]) {
577 vu_peakvals
[ch
] = val
;
579 } else if (vu_times
[ch
]++ > 40) {
581 vu_peakvals
[ch
] = val
;
586 vol
[1]='0'+ch
-(10*(ch
/10));
592 for(i
=0;i
<vu_len
;i
++)
593 if(vu_peaks
[ch
]==i
&& vu_peakvals
[ch
]>0.0f
)
595 else if(i
<=pos
&& val
>0.0f
)
600 if(vu_peakvals
[ch
]>=1.0f
){
602 printf("%c[31m",0x1b); //red color
604 printf("%c[36m",0x1b); // back to cyan
612 if(show_bufferusage
){
613 int num_bufleft
= vringbuffer_writing_size(vringbuffer
);
614 int num_buffers
= (vringbuffer_reading_size(vringbuffer
)+ vringbuffer_writing_size(vringbuffer
));
615 float buflen
= buffers_to_seconds(num_buffers
);
616 float bufleft
= buffers_to_seconds(num_bufleft
);
617 printf("%c[32m",0x1b); // green color
618 printf("Buffer: %.2fs. / %.2fs. "
619 "Disk high priority: [%c]. "
620 "Overruns: %d%c[0m\n",
621 //fmaxf(0.0f,buflen-bufleft),buflen,
623 disk_thread_has_high_priority
?'x':' ',
628 printf("%c[0m",0x1b); // reset colors
629 fprintf(stderr
,"%c[0m",0x1b); // reset colors
635 /////////////////////////////////////////////////////////////////////
636 //////////////////////// Helper thread //////////////////////////////
637 /////////////////////////////////////////////////////////////////////
639 #define MESSAGE_PREFIX ">>> "
641 static char message_string
[5000]={0};
643 static volatile int helper_thread_running
=0;
644 static int init_meterbridge_ports();
646 static bool is_helper_running
=true;
648 static void *helper_thread_func(void *arg
){
649 helper_thread_running
=1;
651 if(use_vu
||show_bufferusage
)
658 init_show_bufferusage();
661 bool move_cursor_to_top_doit
=true;
663 if(message_string
[0]!=0){
664 if(use_vu
|| show_bufferusage
){
665 move_cursor_to_top();
666 printf("%c[%dA",0x1b,1); // move up yet another line.
667 printf("%c[31m",0x1b); // set red color
670 for(lokke
=0;lokke
<vu_len
+5;lokke
++)
673 printf("%c[%dA",0x1b,1); // move up again
676 printf(MESSAGE_PREFIX
);
677 printf(message_string
);
679 move_cursor_to_top_doit
=false;
680 if(use_vu
|| show_bufferusage
)
684 if(use_vu
|| show_bufferusage
)
685 print_console(move_cursor_to_top_doit
,false);
687 if(init_meterbridge_ports()==1 && use_vu
==false && show_bufferusage
==false)
692 }while(is_helper_running
);
695 if(use_vu
|| show_bufferusage
)
696 print_console(true,true);
700 helper_thread_running
=0;
706 static pthread_mutex_t print_message_mutex
= PTHREAD_MUTEX_INITIALIZER
;
707 static void print_message(const char *fmt
, ...){
709 if(helper_thread_running
==0){
712 fprintf(stderr
,"%c[31m" MESSAGE_PREFIX
,0x1b); // set red color
713 vfprintf(stderr
,fmt
,argp
);
714 fprintf(stderr
,"%c[0m",0x1b); // reset colors
718 pthread_mutex_lock(&print_message_mutex
);{
720 while(message_string
[0]!=0)
725 vsprintf(message_string
,fmt
,argp
);
728 }pthread_mutex_unlock(&print_message_mutex
);
734 void setup_helper_thread (void){
735 pthread_create(&helper_thread
, NULL
, helper_thread_func
, NULL
);
738 static void stop_helper_thread(void){
739 //helper_thread_running=0;
740 is_helper_running
=false;
741 pthread_join(helper_thread
, NULL
);
743 if(use_vu
||show_bufferusage
)
744 printf("%c[0m",0x1b); // reset colors
750 /////////////////////////////////////////////////////////////////////
751 //////////////////////// DISK ///////////////////////////////////////
752 /////////////////////////////////////////////////////////////////////
754 // These four variables are used in case we break the 4GB barriere for standard wav files.
755 static int num_files
=1;
756 static int64_t disksize
=0;
757 static bool is_using_wav
=true;
758 static int bytes_per_frame
;
760 static SNDFILE
*soundfile
=NULL
;
761 static int64_t overruns
=0;
764 static FILE *mp3file
= NULL
;
765 static unsigned char *mp3buf
;
766 static int mp3bufsize
;
768 static int open_mp3file(void){
769 buffer_interleaved
= false;
772 print_message("Error. 2 channels supported for mp3 files only. (%d)\n",channels
);
776 mp3bufsize
= buffer_size_in_bytes
* 10;
777 mp3buf
= malloc(mp3bufsize
);
781 print_message("lame_init failed.\n");
785 lame_set_in_samplerate(lame
,(int)jack_samplerate
);
786 lame_set_out_samplerate(lame
,(int)jack_samplerate
);
788 lame_set_quality(lame
,das_lame_quality
);
790 if(das_lame_bitrate
!=-1){
791 lame_set_brate(lame
, das_lame_bitrate
);
792 lame_set_VBR_min_bitrate_kbps(lame
, lame_get_brate(lame
));
796 int ret
= lame_init_params(lame
);
798 print_message("Illegal parameters for lame. (%d)\n",ret
);
803 mp3file
= fopen(filename
,"w");
805 print_message("Can not open file \"%s\" for output (%s)\n", filename
, strerror(errno
));
815 #include "setformat.c"
818 static int open_soundfile(void){
823 if(write_to_stdout
==true)
828 filename
=strdup(base_filename
);
832 if(write_to_mp3
==true)
833 return open_mp3file();
837 /////////////////////////
838 // Code below for sndfile
839 /////////////////////////
841 sf_info
.samplerate
= jack_get_sample_rate (client
);
842 sf_info
.channels
= channels
;
845 int format
=getformat(soundfile_format
);
846 if(format
==-1 && channels
>2){
847 fprintf(stderr
,"Warning, the format \"%s\" is not supported. Using %s instead.\n",soundfile_format_multi
,soundfile_format
);
848 sf_info
.format
=MORE_THAN_TWO_CHANNELS_FORMAT
;
849 }else if(format
==-1){
850 fprintf(stderr
,"Warning, the format \"%s\" is not supported. Using %s instead.\n",soundfile_format_one_or_two
,soundfile_format
);
851 sf_info
.format
=ONE_OR_TWO_CHANNELS_FORMAT
;
853 sf_info
.format
=format
;
856 is_using_wav
= (sf_info
.format
==SF_FORMAT_WAV
)?true:false;
859 case 8: subformat
= SF_FORMAT_PCM_U8
;
861 case 16: subformat
= SF_FORMAT_PCM_16
;
863 case 24: subformat
= SF_FORMAT_PCM_24
;
865 case 32: subformat
= SF_FORMAT_PCM_32
;
868 if(!strcasecmp("flac",soundfile_format
)){
870 subformat
=SF_FORMAT_PCM_24
;
872 }else if(!strcasecmp("ogg",soundfile_format
)){
873 subformat
= SF_FORMAT_VORBIS
;
876 bitdepth
=32; // sizeof(float)*8 would be incorrect in case sizeof(float)!=4
877 subformat
= SF_FORMAT_FLOAT
;
882 bytes_per_frame
=bitdepth
/8;
884 sf_info
.format
|= subformat
;
886 if(sf_format_check(&sf_info
)==0){
887 fprintf (stderr
, "\nFileformat not supported by libsndfile. Try other options.\n");
891 if(write_to_stdout
==true)
892 soundfile
=sf_open_fd(fileno(stdout
),SFM_WRITE
,&sf_info
,false); // ???
894 soundfile
=sf_open(filename
,SFM_WRITE
,&sf_info
);
896 // debugging lines below.
899 if(soundfile
==NULL
){ // || ai==10){
900 fprintf (stderr
, "\nCan not open sndfile \"%s\" for output (%s)\n", filename
,sf_strerror(NULL
));
908 static void close_soundfile(void){
910 if(write_to_stdout
==false){
912 sf_close (soundfile
);
922 print_message("jack_capture failed with a total of %d overruns.\n", total_overruns
);
923 print_message(" try a bigger buffer than -B %f\n",min_buffer_time
);
926 print_message("jack_capture failed with a total of %d disk errors.\n",disk_errors
);
930 // To test filelimit handler, uncomment two next lines.
932 //#define UINT32_MAX 100000+(1024*1024)
934 static int handle_filelimit(size_t frames
){
935 int new_bytes
=frames
*bytes_per_frame
*channels
;
937 if(is_using_wav
&& (disksize
+ ((int64_t)new_bytes
) >= UINT32_MAX
-(1024*1024))){ // (1024*1024) should be enough for the header.
939 sf_close(soundfile
);{
942 filename_new
=my_calloc(1,strlen(base_filename
)+500);
943 sprintf(filename_new
,"%s.%0*d.wav",base_filename
,2,num_files
);
944 print_message("Warning. 4GB limit on wav file almost reached. Closing %s, and continue writing to %s.\n",filename
,filename_new
);
947 filename
=filename_new
;
951 if(!open_soundfile())
961 // stdout_write made by looking at http://mir.dnsalias.com/oss/jackstdout/start
962 // made by Robin Gareus.
963 static int stdout_write(sample_t
*buffer
,size_t frames
){
964 static char *tobuffer
=NULL
;
965 static int bufferlen
=0;
966 int bytes_to_write
=frames
*channels
*2;
968 if(bufferlen
<bytes_to_write
){
970 tobuffer
=my_calloc(1,bytes_to_write
);
971 bufferlen
=bytes_to_write
;
977 for(i
=0;i
<frames
*channels
;i
++){
978 int d
= (int) rint(buffer
[i
]*32767.0);
979 tobuffer
[writeplace
++] = (unsigned char) (d
&0xff);
980 tobuffer
[writeplace
++] = (unsigned char) (((d
&0xff00)>>8)&0xff);
985 int fd
=fileno(stdout
);
986 while(bytes_to_write
> 0){
987 int written
=write(fd
,tobuffer
,bytes_to_write
);
989 fprintf(stderr
,"Error writing to stdout.\n");
992 bytes_to_write
-= written
;
1000 static int mp3_write(void *das_data
,size_t frames
){
1001 sample_t
*data1
=(sample_t
*)das_data
;
1002 sample_t
*data2
=&data1
[frames
];
1004 int size
= lame_encode_buffer_float(lame
, data1
,data2
, frames
, mp3buf
, mp3bufsize
);
1005 //fprintf(stderr,"size: %d\n",size);
1008 fwrite(mp3buf
,size
,1,mp3file
);
1014 static int disk_write(void *data
,size_t frames
){
1016 if(write_to_stdout
==true)
1017 return stdout_write(data
,frames
);
1020 if(write_to_mp3
==true)
1021 return mp3_write(data
,frames
);
1027 if(!handle_filelimit(frames
))
1030 if(sf_writef_float(soundfile
,data
,frames
) != frames
){
1031 print_message("Error. Can not write sndfile (%s)\n",
1032 sf_strerror(soundfile
)
1041 static int disk_write_overruns(int num_overruns
){
1044 "jack_capture failed writing %d frame%s. Some parts of the recording will contain silence.\n"
1045 " Try a bigger buffer than -B %f\n%s",
1046 num_overruns
,num_overruns
==1 ? "" : "s",
1048 is_running
!= 0 ? "Continue recording...\n" : ""
1051 overruns
+=num_overruns
;
1053 while(num_overruns
>0){
1054 int size
=JC_MIN(block_size
,num_overruns
);
1055 if( ! disk_write(empty_buffer
,size
))
1063 static void disk_thread_control_priority(void){
1065 && disk_thread_has_high_priority
==false
1066 && vringbuffer_reading_size(vringbuffer
) >= vringbuffer_writing_size(vringbuffer
)
1069 if(set_high_priority()==true){
1070 disk_thread_has_high_priority
=true;
1071 print_message("Less than half of the buffer used. Setting higher priority for the disk thread.\n");
1073 static bool message_sent
=false;
1074 if(message_sent
==false)
1075 print_message("Error. Could not set higher priority for disk thread.\n");
1082 static void disk_callback(vringbuffer_t
*vrb
,bool first_time
,void *element
){
1083 static bool printed_receive_message
=false;
1084 buffer_t
*buffer
=(buffer_t
*)element
;
1086 if(first_time
==true)
1089 if(use_jack_transport
==true && printed_receive_message
==false){
1090 print_message("Received JackTranportRolling. Recording.\n");
1091 printed_receive_message
=true;
1094 disk_thread_control_priority();
1096 if( buffer
->overruns
> 0)
1097 disk_write_overruns(buffer
->overruns
);
1099 disk_write(buffer
->data
,buffer
->pos
);
1103 static void cleanup_disk(void){
1105 // Adding silence at the end. Not much point.
1106 if(unreported_overruns
>0)
1107 disk_write_overruns(unreported_overruns
);
1112 fprintf(stderr
,"disk thread finished\n");
1119 /////////////////////////////////////////////////////////////////////
1120 //////////////////////// JACK PROCESS ///////////////////////////////
1121 /////////////////////////////////////////////////////////////////////
1124 static void send_buffer_to_disk_thread(buffer_t
*buffer
){
1125 buffer
->overruns
= unreported_overruns
;
1126 vringbuffer_return_writing(vringbuffer
,buffer
);
1127 unreported_overruns
= 0;
1131 static void process_fill_buffer(sample_t
*in
[],buffer_t
*buffer
,int i
,int end
){
1132 sample_t
*data
=buffer
->data
;
1133 int pos
=buffer
->pos
*channels
;
1136 if(buffer_interleaved
== true){
1138 for(ch
=0;ch
<channels
;ch
++){
1139 sample_t val
=in
[ch
][i
];
1148 for(ch
=0;ch
<channels
;ch
++){
1149 sample_t
*curr_in
=in
[ch
];
1150 float max_vu
=vu_vals
[ch
];
1151 for(i
= start_i
; i
<end
; i
++){
1152 sample_t val
=curr_in
[i
];
1153 data
[pos
++]=val
* 32767.9; // weird lame stuff
1158 vu_vals
[ch
] = max_vu
;
1161 //fprintf(stderr,"pos: %d %d\n",pos,channels);
1162 buffer
->pos
=pos
/channels
;
1165 static bool process_new_current_buffer(int frames_left
){
1166 current_buffer
=(buffer_t
*)vringbuffer_get_writing(vringbuffer
);
1167 if(current_buffer
==NULL
){
1169 unreported_overruns
+= frames_left
;
1172 current_buffer
->pos
=0;
1176 static void process_fill_buffers(int jack_block_size
){
1177 sample_t
*in
[channels
];
1180 for(ch
=0;ch
<channels
;ch
++)
1181 in
[ch
]=jack_port_get_buffer(ports
[ch
],jack_block_size
);
1183 if(current_buffer
==NULL
&& process_new_current_buffer(jack_block_size
)==false)
1186 while(i
<jack_block_size
){
1187 int size
=JC_MIN(jack_block_size
- i
,
1188 block_size
- current_buffer
->pos
1191 process_fill_buffer(in
,current_buffer
,i
,i
+size
);
1195 if(current_buffer
->pos
== block_size
){
1196 send_buffer_to_disk_thread(current_buffer
);
1197 if(process_new_current_buffer(jack_block_size
-i
)==false)
1204 static bool jack_transport_started
=false;
1213 static int process_state
=NOT_STARTED
;
1215 static int process(jack_nframes_t nframes
, void *arg
){
1216 jack_transport_state_t state
=0;
1218 if(use_jack_transport
==true){
1219 state
=jack_transport_query(client
,NULL
);
1220 if(state
==JackTransportRolling
){
1221 jack_transport_started
=true;
1225 if(use_jack_transport
==true && jack_transport_started
==false)
1228 if(is_initialized
==0)
1234 if(process_state
==RECORDING_FINISHED
)
1237 if(wait_for_keyboard
==false){ // User has specified a duration
1240 num_frames
=JC_MIN(nframes
,num_frames_to_record
- num_frames_recorded
);
1243 process_fill_buffers(num_frames
);
1245 num_frames_recorded
+= num_frames
;
1247 if(num_frames_recorded
==num_frames_to_record
){
1248 send_buffer_to_disk_thread(current_buffer
);
1249 sem_post(&stop_sem
);
1250 process_state
=RECORDING_FINISHED
;
1254 process_fill_buffers(nframes
);
1255 if(use_jack_transport
==true && state
==JackTransportStopped
){
1256 send_buffer_to_disk_thread(current_buffer
);
1257 sem_post(&stop_sem
);
1258 process_state
=RECORDING_FINISHED
;
1263 vringbuffer_trigger_autoincrease_callback(vringbuffer
);
1273 /////////////////////////////////////////////////////////////////////
1274 /////////////////// METERBRIDGE /////////////////////////////////////
1275 /////////////////////////////////////////////////////////////////////
1278 static char* meterbridge_jackname
;
1279 pid_t meterbridge_pid
;
1280 int meterbridge_started
=0;
1282 static void start_meterbridge(int num_channels
){
1283 meterbridge_jackname
=my_calloc(1,5000);
1285 sprintf(meterbridge_jackname
,"%s_meterbridge",jack_get_client_name(client
));
1286 //meterbridge -t vu -n meterbri xmms-jack_12250_000:out_0 xmms-jack_12250_000:out_1
1288 meterbridge_pid
=fork();
1289 if(meterbridge_pid
==0){
1290 char *argv
[100+num_channels
];
1291 argv
[0]=WHICH_METERBRIDGE
;
1293 argv
[2]=meterbridge_type
;
1295 argv
[4]=meterbridge_jackname
;
1297 argv
[6]=meterbridge_reference
;
1300 for(ch
=0;ch
<num_channels
;ch
++){
1309 if((fd
= open("/dev/null", O_RDWR
| O_CREAT
, S_IRUSR
| S_IWUSR
))==-1){
1312 dup2(fd
,STDOUT_FILENO
);
1313 dup2(fd
,STDERR_FILENO
);
1318 execve(WHICH_METERBRIDGE
,argv
,environ
);
1322 meterbridge_started
=1;
1326 static void wake_up_connection_thread(void);
1327 int connect_meterbridge
=0;
1329 static int init_meterbridge_ports(){
1330 if(ports_meterbridge
!=NULL
|| meterbridge_started
==0)
1334 char portname
[5000];
1335 sprintf(portname
,"%s:meter_1",meterbridge_jackname
);
1336 jack_port_t
*port1
=jack_port_by_name(client
,portname
);
1343 jack_port_t
**ports_meterbridge2
= (jack_port_t
**) my_calloc (sizeof (jack_port_t
*),channels
);
1345 ports_meterbridge2
[0]=port1
;
1348 for(ch
=1;ch
<channels
;ch
++){
1349 sprintf(portname
,"%s:meter_%d",meterbridge_jackname
,ch
+1);
1350 ports_meterbridge2
[ch
]=jack_port_by_name(client
,portname
);
1351 if(ports_meterbridge2
[ch
]==NULL
){
1352 print_message("Warning! Something is very wrong with the meterbridge.\n"); // Well, maybe that port hasn't been initializied yet. Must fix some
1353 free(ports_meterbridge2
);
1358 ports_meterbridge
=ports_meterbridge2
;
1359 connect_meterbridge
=1;
1360 wake_up_connection_thread();
1361 //connect_ports(ports_meterbridge);
1370 /////////////////////////////////////////////////////////////////////
1371 /////////////////// JACK CONNECTIONS ////////////////////////////////
1372 /////////////////////////////////////////////////////////////////////
1375 static int compare(const void *a
, const void *b
){
1376 return strcmp((const char*)a
,(const char*)b
);
1380 static int reconnect_ports_questionmark(void){
1383 for(ch
=0;ch
<channels
;ch
++){
1384 char **connections1
= portnames_get_connections(ch
);
1385 const char **connections2
= jack_port_get_all_connections(client
,ports
[ch
]);
1386 int memb1
=findnumports(connections1
);
1387 int memb2
=findnumports((char**)connections2
);
1396 qsort(connections1
,memb1
,sizeof(char*),compare
);
1397 qsort(connections2
,memb1
,sizeof(char*),compare
);
1401 for(lokke
=0;lokke
<memb1
;lokke
++){
1402 //printf("connect_ports \"%s\" \"%s\" \n",connections1[lokke],connections2[lokke]);
1403 if(strcmp(connections1
[lokke
],connections2
[lokke
])){
1418 static void disconnect_ports(jack_port_t
** ports
){
1424 for(ch
=0;ch
<channels
;ch
++){
1426 const char **connections
= jack_port_get_all_connections(client
,ports
[ch
]);
1429 for(;connections
[lokke
]!=NULL
;lokke
++)
1430 jack_disconnect(client
,connections
[lokke
],jack_port_name(ports
[ch
]));
1437 static void connect_ports(jack_port_t
** ports
){
1443 for(ch
=0;ch
<channels
;ch
++){
1446 char **connections
= portnames_get_connections(ch
);
1448 while(connections
&& connections
[lokke
] != NULL
){
1449 int err
=jack_connect(client
,connections
[lokke
],jack_port_name(ports
[ch
]));
1451 print_message("\nCan not connect input port %s to %s, errorcode %s\n",
1452 jack_port_name (ports
[ch
]), connections
[lokke
],strerror(err
));
1459 static sem_t connection_semaphore
;
1461 static void* connection_thread(void *arg
){
1463 sem_wait(&connection_semaphore
);
1466 if(connect_meterbridge
==1){
1467 connect_ports(ports_meterbridge
);
1468 connect_meterbridge
=0;
1471 if(is_initialized
&& reconnect_ports_questionmark()){
1473 print_message("Reconnecting ports.\n");
1474 disconnect_ports(ports
);
1475 connect_ports(ports
);
1477 disconnect_ports(ports_meterbridge
);
1478 connect_ports(ports_meterbridge
);
1484 fprintf(stderr
,"connection thread finished\n");
1488 static void wake_up_connection_thread(void){
1489 sem_post(&connection_semaphore
);
1492 static void start_connection_thread(void){
1493 sem_init(&connection_semaphore
,0,0);
1494 pthread_create(&connect_thread
,NULL
,connection_thread
,NULL
);
1497 static void stop_connection_thread(void){
1498 wake_up_connection_thread();
1499 pthread_join(connect_thread
, NULL
);
1502 static int graphordercallback(void *arg
){
1503 wake_up_connection_thread();
1509 static void create_ports(void){
1510 ports
= (jack_port_t
**) my_calloc (sizeof (jack_port_t
*),channels
);
1513 for(ch
=0;ch
<channels
;ch
++) {
1515 sprintf(name
,"input%d",ch
+1);
1516 ports
[ch
]=jack_port_register(client
,name
,JACK_DEFAULT_AUDIO_TYPE
,JackPortIsInput
|JackPortIsTerminal
,0);
1518 print_message("Unable to register input port \"%s\"!\n", name
);
1519 jack_client_close(client
);
1531 /////////////////////////////////////////////////////////////////////
1532 /////////////////// INIT / WAIT / SHUTDOWN //////////////////////////
1533 /////////////////////////////////////////////////////////////////////
1536 static void finish(int sig
){
1537 //turn_on_echo(); //Don't think we can do this from a signal handler...
1538 sem_post(&stop_sem
);
1541 static void jack_shutdown(void *arg
){
1542 fprintf(stderr
,"jack_capture: JACK shutdown.\n");
1543 jack_has_been_shut_down
=true;
1544 sem_post(&stop_sem
);
1548 static jack_client_t
*new_jack_client(char *name
){
1549 jack_status_t status
;
1550 jack_client_t
*client
=jack_client_open(name
,JackNoStartServer
,&status
,NULL
);
1553 print_message("jack_client_open() failed, "
1554 "status = 0x%2.0x\n", status
);
1562 static void start_jack(void){
1563 static bool I_am_already_called
=false;
1564 if(I_am_already_called
) // start_jack is called more than once if the --port argument has been used.
1567 client
=new_jack_client("jack_capture");
1569 jack_samplerate
=jack_get_sample_rate(client
);
1570 block_size
=jack_get_buffer_size(client
);
1572 I_am_already_called
=true;
1577 static pthread_t keypress_thread
={0};
1578 static void* keypress_func(void* arg
){
1581 fgets(gakk
,49,stdin
);
1583 sem_post(&stop_sem
);
1587 static void start_keypress_thread(void){
1588 pthread_create(&keypress_thread
, NULL
, keypress_func
, NULL
);
1591 static const char *advanced_help
=
1592 "jack_capture [--bitdepth n] [--channels n] [--port port] [filename]\n"
1593 " [ -b n] [ -c n] [ -p port]\n"
1595 "\"bitdepth\" is by default FLOAT. It can be set to either 8, 16, 24 or 32. (for relevant formats)\n"
1596 "\"channels\" is by default 2.\n"
1597 "\"port\" is by default set to the two first physical outputs. The \"port\" argument can be\n"
1598 " specified more than once.\n"
1599 "\"filename\" is by default auotogenerated to \"jack_capture_<number>.<format>\"\n"
1602 "Additional arguments:\n"
1603 "[--duration s] or [-d s] -> Recording is stopped after \"s\" seconds.\n"
1604 "[--leading-zeros n] or [-z n] -> \"n\" is the number of zeros to in the autogenerated filename.\n"
1605 " (-z 2 -> jack_capture_001.wav, and so on.) (default is 1)\n"
1606 "[--format format] or [-f format] -> Selects fileformat provided by libsndfile.\n"
1607 " See http://www.mega-nerd.com/libsndfile/api.html#open\n"
1608 " (Default is wav for 1 or 2 channels, and wavex for more than 2.)\n"
1609 "[--print-formats] or [-pf] -> Prints all sound formats provided to sndfile to screen and then\n"
1611 "[--version] or [-v] -> Prints out version.\n"
1612 "[--silent] or [-s] -> Suppresses some common messages printed to the terminal.\n"
1613 "[--verbose] or [-V] -> Prints some extra information to the terminal.\n"
1614 "[--mp3] or [-mp3] -> Writes to an mp3 file using liblame (LAME).\n"
1615 " (the --format option has no effect using this option)\n"
1616 "[--mp3-quality n] or [-mp3q n] -> Selects mp3 quality provided by liblame. n=0 is best, n=9 is worst.\n"
1617 " Default n is 2. (0 uses the most amount of CPU, 9 uses the least)\n"
1618 "[--mp3-bitrate n] or [-mp3b n] -> Selects mp3 bitrate (in kbit/s).\n"
1619 " Default is set by liblame. (currently 128)\n"
1620 "[--write-to-stdout] or [-ws] -> Writes 16 bit little endian to stdout. (the --format option, the\n"
1621 " --mp3 option, and some others have no effect using this option)\n"
1622 "[--disable-meter] or [-dm] -> Disable console meter.\n"
1623 "[--hide-buffer-usage] or [-hbu] -> Disable buffer usage updates in the console.\n"
1624 "[--disable-console] or [-dc] -> Disable console updates. Same as \"-dm -hbu\".\n"
1625 "[--linear-meter] or [-lm] -> Use linear scale for the console meter (default is dB scale)\n"
1626 "[--dB-meter-reference or [-dBr] -> Specify reference level for dB meter. (default=0)\n"
1627 "[--meterbridge] or [-mb] -> Start up meterbridge to monitor recorded sound.\n"
1628 "[--meterbridge-type] or [-mt] -> Specify type. vu (default), ppm, dpm, jf or sco.\n"
1629 "[--meterbridge-reference]/[-mr] -> Specify reference level for meterbidge.\n"
1630 "[--jack-transport]/[-jt] -> Start program, but do not start recording until jack transport has started rolling\n"
1631 " When jack transport stops, the recording is also stopped, and the program ends.\n"
1632 "[--jack-transport-multi]/[-jtm] -> Similar to --jack-transport, but do not end program when jack transport stops.\n"
1633 " Instead, record to a new file when jack_transport starts rolling again.\n"
1634 " (not implemented yet)\n"
1635 "[--bufsize s] or [-B s] -> Initial/minimum buffer size in seconds. Default is 8 seconds\n"
1636 " for mp3 files, and 4 seconds for all other formats.\n"
1637 "[--maxbufsize] or [-MB] -> Maximum buffer size in seconds jack_capture will allocate.\n"
1638 " Default is 40. (Buffer is automatically increased during\n"
1639 " recording when needed. But it will never go beyond this size.)\n"
1640 "[--filename] or [-fn] -> Specify filename.\n"
1641 " (It's usually easier to set last argument instead)\n"
1645 "To record a stereo file of what you hear:\n"
1648 "To record a stereo file of what you hear in the flac format:\n"
1649 " $jack_capture -f flac\n"
1651 "To record a stereo file of what you hear in the ogg format:\n"
1652 " $jack_capture -f ogg\n"
1654 "To record a stereo file of what you hear in the mp3 format:\n"
1655 " $jack_capture -mp3\n"
1657 "To record a stereo file of what you hear in the wav format:\n"
1658 " $jack_capture --port system:playback_1 --port system:playback_2\n"
1659 "****************************************************************************\n"
1660 "**** NOTE! The above example does _exactly_ the same as the default!!! ****\n"
1661 "****************************************************************************\n"
1663 "Same result as above, but using a different syntax:\n"
1664 " $jack_capture --channels 2 --port system:playback*\n"
1666 "To record the output from jamin:\n"
1667 " $jack_capture --port jamin:out* sound_from_jamin.wav\n"
1669 "To record all sound coming in to jamin:\n"
1670 " $jack_capture --port jamin:in* sound_to_jamin.wav\n"
1672 "To record all sound coming in and out of jamin:\n"
1673 " $jack_capture --port jamin* sound_to_and_from_jamin.wav\n"
1675 "To record a stereo file from the soundcard:\n"
1676 " $jack_capture -c 2 -p system:capture*\n"
1679 void init_arguments(int argc
, char *argv
[]){
1682 "To record what you hear, just run\n"
1686 "To list advanced options, run\n"
1688 " jack_capture --advanced-options\n"
1692 OPTARG("--advanced-options","--help2") printf(advanced_help
);exit(0);
1693 OPTARG("--bitdepth","-b") bitdepth
= OPTARG_GETINT();
1694 OPTARG("--bufsize","-B") min_buffer_time
= OPTARG_GETFLOAT(); min_buffer_time
=JC_MAX(0.01,min_buffer_time
);
1695 OPTARG("--maxbufsize","-MB") max_buffer_time
= OPTARG_GETFLOAT();
1696 OPTARG("--channels","-c") channels
= OPTARG_GETINT();
1697 OPTARG("--leading-zeros","-z") leading_zeros
= OPTARG_GETINT();
1698 OPTARG("--recording-time","-d"){
1699 recording_time
= OPTARG_GETFLOAT();
1701 num_frames_to_record
=seconds_to_frames(recording_time
);
1702 wait_for_keyboard
=false;
1704 OPTARG("--port","-p") start_jack() ; portnames_add(OPTARG_GETSTRING());
1705 OPTARG("--format","-f"){
1706 soundfile_format
=OPTARG_GETSTRING();
1707 if(!strcmp("mp3",soundfile_format
)){
1708 write_to_mp3
= true;
1710 soundfile_format_is_set
=true;
1712 OPTARG("--version","-v") puts(VERSION
);exit(0);
1713 OPTARG("--silent","-s") silent
=true;
1714 OPTARG("--verbose","-V") verbose
=true;
1715 OPTARG("--print-formats","-pf") print_all_formats();exit(0);
1716 OPTARG("--mp3","-mp3") write_to_mp3
= true;
1717 OPTARG("--mp3-quality","-mp3q") das_lame_quality
= OPTARG_GETINT(); write_to_mp3
= true;
1718 OPTARG("--mp3-bitrate","-mp3b") das_lame_bitrate
= OPTARG_GETINT(); write_to_mp3
= true;
1719 OPTARG("--write-to-stdout","-ws") write_to_stdout
=true;use_vu
=false;show_bufferusage
=false;
1720 OPTARG("--disable-meter","-dm") use_vu
=false;
1721 OPTARG("--hide-buffer-usage","-hbu") show_bufferusage
=false;
1722 OPTARG("--disable-console","-dc") use_vu
=false;show_bufferusage
=false;
1723 OPTARG("--linear-meter","-lm") vu_dB
=false;
1724 OPTARG("--dB-meter-reference","-dBr") vu_dB
=true;vu_bias
=powf(10.0f
,OPTARG_GETFLOAT()*-0.05f
);//from meterbridge
1725 OPTARG("--meterbridge","-mb") use_meterbridge
=true;
1726 OPTARG("--meterbridge-type","-mt") use_meterbridge
=true;meterbridge_type
=OPTARG_GETSTRING();
1727 OPTARG("--meterbridge-reference","-mr") use_meterbridge
=true;meterbridge_reference
=OPTARG_GETSTRING();
1728 OPTARG("--jack-transport","-jt") use_jack_transport
=true;
1729 OPTARG("--filename","-fn") base_filename
=OPTARG_GETSTRING();
1730 OPTARG_LAST() base_filename
=OPTARG_GETSTRING();
1734 if(write_to_mp3
==true){
1736 soundfile_format
="mp3";
1737 soundfile_format_is_set
=true;
1738 if(min_buffer_time
<=0.0f
)
1739 min_buffer_time
= DEFAULT_MIN_MP3_BUFFER_TIME
;
1741 fprintf(stderr
,"mp3 not supported. liblame was not installed when compiling jack_capture\n");
1745 if(min_buffer_time
<=0.0f
)
1746 min_buffer_time
= DEFAULT_MIN_BUFFER_TIME
;
1749 verbose_print("main() find default file format\n");
1750 if(soundfile_format_is_set
==false){
1752 soundfile_format
=soundfile_format_multi
;
1754 soundfile_format
=soundfile_format_one_or_two
;
1758 verbose_print("main() find filename\n");
1761 if(base_filename
==NULL
){
1763 base_filename
=my_calloc(1,5000);
1765 sprintf(base_filename
,"jack_capture_%0*d.%s",leading_zeros
+1,++try,soundfile_format
);
1766 if(access(base_filename
,F_OK
)) break;
1775 void init_various(void){
1776 verbose_print("main() init jack 1\n");
1779 start_connection_thread();
1781 portnames_add_defaults();
1784 verbose_print("main() init buffers\n");
1790 verbose_print("main() Open soundfile and setup disk callback.\n");
1791 // Open soundfile and start disk thread
1793 if(!open_soundfile()){
1794 jack_client_close(client
);
1798 vringbuffer_set_receiver_callback(vringbuffer
,disk_callback
);
1801 verbose_print("main() Init waiting.\n");
1804 sem_init(&stop_sem
,0,0);
1805 signal(SIGINT
,finish
);
1806 signal(SIGTERM
,finish
);
1807 if(wait_for_keyboard
==true)
1808 start_keypress_thread();
1811 verbose_print("main() Init jack 2.\n");
1814 jack_set_process_callback(client
, process
, NULL
);
1816 jack_on_shutdown(client
, jack_shutdown
, NULL
);
1818 jack_set_graph_order_callback(client
,graphordercallback
,NULL
);
1820 if (jack_activate(client
)) {
1821 fprintf (stderr
,"\nCan not activate client");
1826 connect_ports(ports
);
1830 verbose_print("main() Everything initialized.\n");
1831 // Everything initialized.
1832 // (The threads are waiting for this variable, not the other way around, so now it just needs to be set.)
1835 wake_up_connection_thread(); // Usually (?) not necessarry, but just in case.
1838 verbose_print("main() Start meterbridge.\n");
1839 // Start meterbridge
1842 start_meterbridge(channels
);
1845 verbose_print("main() Print some info.\n");
1848 if(wait_for_keyboard
==false){ // User has specified a duration
1851 "Recording to \"%s\". The recording is going\n"
1852 MESSAGE_PREFIX
"to last %lf seconds Press <Ctrl-C> to stop before that.\n",
1857 print_message("Recording to \"%s\". Press <Return> or <Ctrl-C> to stop.\n",base_filename
);
1858 //fprintf(stderr,"Recording to \"%s\". Press <Return> or <Ctrl-C> to stop.\n",base_filename);
1862 verbose_print("main() Start helper thread.\n");
1863 // Start the helper thread, which takes care of the console
1865 setup_helper_thread();
1873 void wait_until_recording_finished(void){
1874 verbose_print("main() Wait.\n");
1876 if(use_jack_transport
==true)
1877 print_message("Waiting for JackTransportRolling.\n");
1879 sem_wait(&stop_sem
);
1881 if(helper_thread_running
==1){
1882 // if(use_vu || show_bufferusage)
1883 // printf("%c[%dA",0x1b,1); // Pressing return moves the cursor.
1884 if(silent
==false) // messy...
1885 print_message("Please wait while writing all data to disk. (shouldn't take long)\n");
1886 //print_message("%c[%dAPlease wait while writing all data to disk. (shouldn't take long)\n",0x1b,1); // necessary.
1892 void stop_recording_and_cleanup(void){
1893 verbose_print("main() Stop recording and clean up.\n");
1897 stop_connection_thread();
1899 if(jack_has_been_shut_down
==false)
1900 jack_client_close(client
);
1902 vringbuffer_stop_callbacks(vringbuffer
); // Called before cleanup_disk to make sure all data are sent to the callback.
1906 if(meterbridge_started
)
1907 kill(meterbridge_pid
,SIGINT
);
1909 stop_helper_thread();
1912 fprintf(stderr
,"%c[31m",0x1b); //red color
1913 fprintf(stderr
,"Finished.");
1914 fprintf(stderr
,"%c[0m",0x1b); // reset colors
1915 fprintf(stderr
,"\n");
1920 int main (int argc
, char *argv
[]){
1924 init_arguments(argc
,argv
);
1928 wait_until_recording_finished();
1930 stop_recording_and_cleanup();