mirror of
https://github.com/game-stop/veejay.git
synced 2026-06-16 04:31:23 +02:00
enable direct passthrough when source has no audio (write silence instead), keep audio producer alive for external monitor output, skip empty sequencer ids, ignore sample speed 0 by restoring previous speed or 1 in midi/sequencer mode, resume from stuck play, reset stats/loops type changes
This commit is contained in:
@@ -2137,6 +2137,9 @@ void veejay_sample_set_initial_positions(veejay_t *info)
|
||||
|
||||
int id = info->seq->samples[i].sample_id;
|
||||
|
||||
if(id <= 0 || !sample_exists(id))
|
||||
continue;
|
||||
|
||||
sample_set_loops(id, -1);
|
||||
|
||||
sample_set_resume_override(id, -1);
|
||||
@@ -2182,10 +2185,14 @@ void veejay_reset_sample_positions(veejay_t *info, int sample_id)
|
||||
if( info->seq->samples[i].type != 0 )
|
||||
continue;
|
||||
int id = info->seq->samples[i].sample_id;
|
||||
if(id <= 0 || !sample_exists(id))
|
||||
continue;
|
||||
veejay_prepare_sample_positions(id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(sample_id <= 0 || !sample_exists(sample_id))
|
||||
return;
|
||||
veejay_prepare_sample_positions(sample_id);
|
||||
}
|
||||
}
|
||||
@@ -4553,6 +4560,9 @@ static inline int vj_audio_is_external_jack_monitor_source(
|
||||
source != VJ_AUDIO_SYNC_SOURCE_WAV_FILE)
|
||||
return 0;
|
||||
|
||||
if(source == VJ_AUDIO_SYNC_SOURCE_WAV_FILE)
|
||||
return audio_source != VJ_RECORD_AUDIO_SOURCE_SILENCE;
|
||||
|
||||
return (audio_source == VJ_RECORD_AUDIO_SOURCE_BEAT_JACK ||
|
||||
audio_source == VJ_RECORD_AUDIO_SOURCE_AUTO);
|
||||
}
|
||||
@@ -4973,11 +4983,27 @@ void *veejay_audio_producer_thread(void *arg)
|
||||
veejay_t *info = (veejay_t *)arg;
|
||||
video_playback_setup *settings = info->settings;
|
||||
editlist *el = info->current_edit_list;
|
||||
int audio_channels = 2;
|
||||
int BPS = 4;
|
||||
int media_audio = 0;
|
||||
|
||||
int has_audio = (info->current_edit_list->has_audio &&
|
||||
vj_perform_init_audio(info,0) &&
|
||||
vj_perform_init_audio(info, 1) &&
|
||||
info->audio == AUDIO_PLAY);
|
||||
if(el) {
|
||||
if(el->audio_chans > 0 && el->audio_chans <= 2)
|
||||
audio_channels = el->audio_chans;
|
||||
if(el->audio_bps > 0)
|
||||
BPS = el->audio_bps;
|
||||
}
|
||||
|
||||
media_audio = (el && el->has_audio &&
|
||||
vj_perform_init_audio(info,0) &&
|
||||
vj_perform_init_audio(info,1) &&
|
||||
info->audio == AUDIO_PLAY);
|
||||
|
||||
#ifdef HAVE_JACK
|
||||
int has_audio = (info->audio == AUDIO_PLAY);
|
||||
#else
|
||||
int has_audio = media_audio;
|
||||
#endif
|
||||
#ifndef HAVE_JACK
|
||||
has_audio = 0;
|
||||
#endif
|
||||
@@ -5004,7 +5030,6 @@ void *veejay_audio_producer_thread(void *arg)
|
||||
double slow_video_phase = 0.0;
|
||||
int last_dynamic_slow = 0;
|
||||
unsigned long long loop_count = 0;
|
||||
const int BPS = el->audio_bps;
|
||||
const int MAX_CLIENT_FRAMES = (int)(((double)CLIENT_RATE / VJ_DYNAMIC_ALLOC_MIN_FPS) + 4096.0);
|
||||
|
||||
uint8_t *audio_chunk = NULL;
|
||||
@@ -5154,6 +5179,18 @@ void *veejay_audio_producer_thread(void *arg)
|
||||
) &&
|
||||
external_tape_neutral_dbg &&
|
||||
!audio_mute_dbg;
|
||||
int external_monitor_audio =
|
||||
vj_audio_is_external_jack_monitor_source(
|
||||
settings,
|
||||
audio_source_dbg,
|
||||
audio_sync_mode_dbg,
|
||||
audio_sync_enabled_dbg
|
||||
) &&
|
||||
!audio_mute_dbg;
|
||||
int external_direct_passthrough =
|
||||
external_monitor_audio &&
|
||||
external_live_source_dbg &&
|
||||
atomic_load_int(&settings->audio_sync.source) == VJ_AUDIO_SYNC_SOURCE_JACK;
|
||||
|
||||
if(vj_jack_xrun_flag()) {
|
||||
|
||||
@@ -5171,7 +5208,28 @@ void *veejay_audio_producer_thread(void *arg)
|
||||
}
|
||||
|
||||
int tx_active = atomic_load_int(&settings->transition.active) && atomic_load_int(&settings->transition.global_state);
|
||||
if(!tx_active) {
|
||||
if(external_monitor_audio) {
|
||||
#ifdef HAVE_JACK
|
||||
vj_jack_set_input_passthrough(external_direct_passthrough ? 1 : 0);
|
||||
#endif
|
||||
if(external_direct_passthrough) {
|
||||
veejay_memset(audio_chunk, 0, (size_t)needed * (size_t)BPS);
|
||||
decoded = needed;
|
||||
} else {
|
||||
decoded = vj_audio_sync_render_monitor_s16(&settings->audio_sync,
|
||||
audio_chunk,
|
||||
needed,
|
||||
BPS,
|
||||
audio_channels,
|
||||
CLIENT_RATE);
|
||||
|
||||
if(decoded <= 0) {
|
||||
veejay_memset(audio_chunk, 0, (size_t)needed * (size_t)BPS);
|
||||
decoded = needed;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(media_audio && !tx_active) {
|
||||
decoded = vj_perform_queue_audio_chunk_ext(info, needed, media_frame, 0, audio_chunk);
|
||||
|
||||
if (decoded <= 0) {
|
||||
@@ -5192,12 +5250,19 @@ void *veejay_audio_producer_thread(void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if(media_audio) {
|
||||
long long b_frame = vj_calc_next_subframe(info, settings->transition.next_id);
|
||||
long long start = atomic_load_long_long(&settings->transition.start);
|
||||
long long end = atomic_load_long_long(&settings->transition.end);
|
||||
decoded = vj_perform_queue_audio_chunk_crossfade(info, needed, media_frame, b_frame, audio_chunk, settings->transition.next_id,start,end);
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_JACK
|
||||
vj_jack_set_input_passthrough(0);
|
||||
#endif
|
||||
veejay_memset(audio_chunk, 0, (size_t)needed * (size_t)BPS);
|
||||
decoded = needed;
|
||||
}
|
||||
|
||||
int frames_written = 0;
|
||||
int write_pos = 0;
|
||||
@@ -7496,13 +7561,34 @@ int veejay_toggle_audio(veejay_t * info, int audio)
|
||||
|
||||
(void) audio;
|
||||
|
||||
if( !(el->has_audio) ) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING,
|
||||
#ifdef HAVE_JACK
|
||||
int external_audio = vj_audio_is_external_jack_monitor_source(
|
||||
settings,
|
||||
atomic_load_int(&settings->record_audio_source),
|
||||
atomic_load_int(&settings->audio_sync.mode),
|
||||
vj_audio_sync_is_enabled(&settings->audio_sync)
|
||||
);
|
||||
#else
|
||||
int external_audio = 0;
|
||||
#endif
|
||||
|
||||
int silent_output = (info->audio == AUDIO_PLAY &&
|
||||
el &&
|
||||
!el->has_audio &&
|
||||
el->audio_rate > 0 &&
|
||||
el->audio_chans > 0 &&
|
||||
el->audio_bps > 0);
|
||||
|
||||
if((!el || !(el->has_audio)) && !external_audio && !silent_output) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING,
|
||||
"Audio playback has not been enabled");
|
||||
info->audio = NO_AUDIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(external_audio || silent_output)
|
||||
info->audio = AUDIO_PLAY;
|
||||
|
||||
old_mute = atomic_load_int(&settings->audio_mute) ? 1 : 0;
|
||||
new_mute = old_mute ? 0 : 1;
|
||||
|
||||
|
||||
@@ -4315,6 +4315,11 @@ void vj_event_sample_set_rand_loop(void *ptr, const char format[], va_list ap)
|
||||
|
||||
SAMPLE_DEFAULTS(args[0]);
|
||||
|
||||
if(v->seq && v->seq->active && sample_exists(args[0])) {
|
||||
sample_set_loop_stats(args[0], 0);
|
||||
sample_set_loops(args[0], -1);
|
||||
}
|
||||
|
||||
if( args[1] == -1 )
|
||||
{
|
||||
if( sample_exists(args[0]) )
|
||||
@@ -4351,6 +4356,13 @@ void vj_event_sample_set_loop_type(void *ptr, const char format[], va_list ap)
|
||||
return;
|
||||
}
|
||||
|
||||
if(v->seq && v->seq->active) {
|
||||
sample_set_loop_stats(args[0], 0);
|
||||
sample_set_loops(args[0], -1);
|
||||
if(args[1] == 0)
|
||||
args[1] = 4;
|
||||
}
|
||||
|
||||
if(args[1] == -1) {
|
||||
int lp = sample_get_looptype(args[0]);
|
||||
if( lp == 1 && args[1] == -1 )
|
||||
@@ -4458,6 +4470,12 @@ void vj_event_sample_set_speed(void *ptr, const char format[], va_list ap)
|
||||
|
||||
SAMPLE_DEFAULTS(args[0]);
|
||||
|
||||
if(v->seq && v->seq->active && args[1] == 0) {
|
||||
args[1] = v->settings->previous_playback_speed;
|
||||
if(args[1] == 0)
|
||||
args[1] = 1;
|
||||
}
|
||||
|
||||
if( sample_set_speed(args[0], args[1]) != -1)
|
||||
{
|
||||
veejay_msg(VEEJAY_MSG_INFO, "Changed speed of sample %d to %d",args[0],args[1]);
|
||||
@@ -12651,6 +12669,13 @@ void vj_event_sample_sequencer_active(void *ptr, const char format[], va_list ap
|
||||
vj_tag_set_loops(cur_id, -1);
|
||||
}
|
||||
|
||||
if(v->settings && v->settings->current_playback_speed == 0) {
|
||||
int resume_speed = v->settings->previous_playback_speed;
|
||||
if(resume_speed == 0)
|
||||
resume_speed = 1;
|
||||
veejay_set_speed(v, resume_speed, 0);
|
||||
}
|
||||
|
||||
veejay_msg(VEEJAY_MSG_INFO,"Sample sequencer disabled; current source keeps looping");
|
||||
return;
|
||||
}
|
||||
@@ -12688,6 +12713,13 @@ void vj_event_sample_sequencer_active(void *ptr, const char format[], va_list ap
|
||||
|
||||
v->seq->active = 1;
|
||||
|
||||
if(v->settings && v->settings->current_playback_speed == 0) {
|
||||
int resume_speed = v->settings->previous_playback_speed;
|
||||
if(resume_speed == 0)
|
||||
resume_speed = 1;
|
||||
veejay_set_speed(v, resume_speed, 0);
|
||||
}
|
||||
|
||||
veejay_reset_sample_positions(v, -1);
|
||||
|
||||
veejay_change_playback_mode(v, playback_mode, next_sample_id);
|
||||
@@ -12952,5 +12984,4 @@ void vj_event_alpha_composite(void *ptr, const char format[], va_list ap)
|
||||
v->settings->alpha_value = 255;
|
||||
veejay_msg(VEEJAY_MSG_INFO,"New alpha mask every frame (default alpha value is %d)", v->settings->alpha_value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -475,6 +475,62 @@ static inline int vj_perform_clampi(int v, int lo, int hi)
|
||||
return (v < lo) ? lo : ((v > hi) ? hi : v);
|
||||
}
|
||||
|
||||
#ifndef VJ_SILENCE_AUDIO_RATE
|
||||
#define VJ_SILENCE_AUDIO_RATE 48000
|
||||
#endif
|
||||
#ifndef VJ_SILENCE_AUDIO_CHANS
|
||||
#define VJ_SILENCE_AUDIO_CHANS 2
|
||||
#endif
|
||||
#ifndef VJ_SILENCE_AUDIO_BITS
|
||||
#define VJ_SILENCE_AUDIO_BITS 16
|
||||
#endif
|
||||
|
||||
static inline editlist *vj_perform_audio_editlist(veejay_t *info)
|
||||
{
|
||||
if(!info)
|
||||
return NULL;
|
||||
return info->current_edit_list ? info->current_edit_list : info->edit_list;
|
||||
}
|
||||
|
||||
static inline int vj_perform_audio_params_valid(const editlist *el)
|
||||
{
|
||||
return el &&
|
||||
el->video_fps > 0.0 &&
|
||||
el->audio_rate > 0 &&
|
||||
el->audio_chans > 0 &&
|
||||
el->audio_bits > 0 &&
|
||||
el->audio_bps > 0;
|
||||
}
|
||||
|
||||
static inline int vj_perform_audio_media_valid(const editlist *el)
|
||||
{
|
||||
return el && el->has_audio && vj_perform_audio_params_valid(el);
|
||||
}
|
||||
|
||||
#ifdef HAVE_JACK
|
||||
static int vj_perform_prepare_silence_audio_params(editlist *el)
|
||||
{
|
||||
if(!el || el->video_fps <= 0.0)
|
||||
return 0;
|
||||
|
||||
if(el->audio_rate <= 0)
|
||||
el->audio_rate = VJ_SILENCE_AUDIO_RATE;
|
||||
|
||||
if(el->audio_chans <= 0)
|
||||
el->audio_chans = VJ_SILENCE_AUDIO_CHANS;
|
||||
else if(el->audio_chans > 2)
|
||||
el->audio_chans = 2;
|
||||
|
||||
if(el->audio_bits <= 0 || (el->audio_bits % 8) != 0)
|
||||
el->audio_bits = VJ_SILENCE_AUDIO_BITS;
|
||||
|
||||
if(el->audio_bps <= 0)
|
||||
el->audio_bps = el->audio_chans * (el->audio_bits / 8);
|
||||
|
||||
return vj_perform_audio_params_valid(el);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define CACHE_TOP 0
|
||||
#define CACHE 1
|
||||
@@ -1888,37 +1944,51 @@ static void vj_perform_record_buffer_free(performer_global_t *g)
|
||||
|
||||
int vj_init_audio_fader_luts(veejay_t *info) {
|
||||
performer_global_t *global = (performer_global_t*) info->performer;
|
||||
editlist *el = vj_perform_audio_editlist(info);
|
||||
|
||||
const int audio_rate = info->current_edit_list->audio_rate;
|
||||
const double video_fps = info->current_edit_list->video_fps;
|
||||
if(!global)
|
||||
return 0;
|
||||
|
||||
if(!vj_perform_audio_media_valid(el)) {
|
||||
if(el && !el->has_audio)
|
||||
veejay_msg(VEEJAY_MSG_INFO, "[AUDIO] No embedded audio stream; audio mixer runs silent");
|
||||
else
|
||||
veejay_msg(VEEJAY_MSG_WARNING, "[AUDIO] Invalid embedded audio parameters; audio mixer disabled");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int audio_rate = el->audio_rate;
|
||||
const double video_fps = el->video_fps;
|
||||
const int frame_bytes = el->audio_bps;
|
||||
const int max_samples_per_frame = (int)ceil((double)audio_rate / video_fps);
|
||||
size_t buffer_size = max_samples_per_frame * info->current_edit_list->audio_bps;
|
||||
|
||||
global->fade_lut = (float*) vj_calloc( sizeof(float) * buffer_size);
|
||||
if(!global->fade_lut) {
|
||||
return 0;
|
||||
}
|
||||
global->gain_lut[0] = (float*) vj_calloc( (sizeof(float) * buffer_size));
|
||||
if(!global->gain_lut[0]) {
|
||||
return 0;
|
||||
if(max_samples_per_frame < 2 || frame_bytes <= 0) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING, "[AUDIO] Invalid mixer geometry; audio mixer disabled");
|
||||
return 1;
|
||||
}
|
||||
|
||||
global->gain_lut[1] = (float*) vj_calloc( (sizeof(float) * buffer_size));
|
||||
if(!global->gain_lut[1]) {
|
||||
size_t buffer_size = (size_t)max_samples_per_frame * (size_t)frame_bytes;
|
||||
|
||||
global->fade_lut = (float*) vj_calloc(sizeof(float) * buffer_size);
|
||||
if(!global->fade_lut)
|
||||
return 0;
|
||||
|
||||
global->gain_lut[0] = (float*) vj_calloc(sizeof(float) * buffer_size);
|
||||
if(!global->gain_lut[0])
|
||||
return 0;
|
||||
|
||||
global->gain_lut[1] = (float*) vj_calloc(sizeof(float) * buffer_size);
|
||||
if(!global->gain_lut[1])
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < max_samples_per_frame; i++) {
|
||||
float t = (float)i / (float)(max_samples_per_frame - 1);
|
||||
|
||||
global->gain_lut[0][i] = cosf(t * (M_PI / 2.0f));
|
||||
global->gain_lut[1][i] = sinf(t * (M_PI / 2.0f));
|
||||
|
||||
global->fade_lut[i] = t;
|
||||
}
|
||||
|
||||
|
||||
global->gain_lut[0][max_samples_per_frame - 1] = 0.0f;
|
||||
global->gain_lut[0][max_samples_per_frame - 2] = 0.0f;
|
||||
|
||||
@@ -1933,6 +2003,7 @@ int vj_init_audio_fader_luts(veejay_t *info) {
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "[AudioMix] LUT[0] : out=%.3f in=%.3f (start)", global->gain_lut[0][0], global->gain_lut[1][0]);
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "[AudioMix] LUT[%d] : out=%.3f in=%.3f (mid)", mid, global->gain_lut[0][mid], global->gain_lut[1][mid]);
|
||||
veejay_msg(VEEJAY_MSG_DEBUG, "[AudioMix] LUT[%d] : out=%.3f in=%.3f (end)", last, global->gain_lut[0][last], global->gain_lut[1][last]);
|
||||
|
||||
float energy_mid = global->gain_lut[0][mid] * global->gain_lut[0][mid] +
|
||||
global->gain_lut[1][mid] * global->gain_lut[1][mid];
|
||||
|
||||
@@ -2286,10 +2357,15 @@ static void vj_perform_close_audio(performer_t *p) {
|
||||
|
||||
int init_audio_resampler(veejay_t *info, performer_t *p) {
|
||||
#ifdef HAVE_JACK
|
||||
const int chans = info->edit_list->audio_chans;
|
||||
const int rate = info->edit_list->audio_rate;
|
||||
editlist *el = vj_perform_audio_editlist(info);
|
||||
|
||||
p->audio_scratcher = vj_scratch_init( chans, rate, info->edit_list->video_fps );
|
||||
if(!vj_perform_audio_media_valid(el))
|
||||
return 1;
|
||||
|
||||
const int chans = el->audio_chans;
|
||||
const int rate = el->audio_rate;
|
||||
|
||||
p->audio_scratcher = vj_scratch_init(chans, rate, el->video_fps);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@@ -2307,7 +2383,13 @@ int vj_perform_init_audio(veejay_t * info, int AorB)
|
||||
}
|
||||
|
||||
performer_global_t *global = (performer_global_t*) info->performer;
|
||||
editlist *el = info->edit_list;
|
||||
editlist *el = vj_perform_audio_editlist(info);
|
||||
|
||||
if(!vj_perform_audio_media_valid(el)) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING, "[AUDIO] Skipping media audio buffers: no valid embedded audio stream");
|
||||
return 0;
|
||||
}
|
||||
|
||||
performer_t *p = (AorB ? global->A : global->B);
|
||||
double samples_per_frame = (double)el->audio_rate / (double)el->video_fps;
|
||||
const uint32_t sample_len = ceil(samples_per_frame) * el->audio_bps;
|
||||
@@ -2568,54 +2650,85 @@ int vj_perform_preview_max_height(veejay_t *info) {
|
||||
|
||||
int vj_perform_audio_start(veejay_t * info)
|
||||
{
|
||||
editlist *el = info->edit_list;
|
||||
editlist *el = info ? info->edit_list : NULL;
|
||||
|
||||
if (el->has_audio)
|
||||
{
|
||||
#ifdef HAVE_JACK
|
||||
vj_jack_initialize();
|
||||
|
||||
int res = vj_jack_init_duplex(el);
|
||||
|
||||
if( res <= 0 ) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING,
|
||||
"[AUDIO] Jack duplex start failed; falling back to playback-only mode");
|
||||
|
||||
vj_jack_initialize();
|
||||
res = vj_jack_init(el);
|
||||
}
|
||||
|
||||
if( res <= 0 ) {
|
||||
veejay_msg(0, "[AUDIO] Audio playback disabled");
|
||||
info->audio = NO_AUDIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( res == 2 )
|
||||
{
|
||||
vj_jack_stop();
|
||||
info->audio = NO_AUDIO;
|
||||
veejay_msg(VEEJAY_MSG_ERROR,"Please run jackd with a sample rate of %ld",el->audio_rate );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(vj_jack_has_input())
|
||||
veejay_msg(VEEJAY_MSG_DEBUG,"[AUDIO] Jack audio playback started with capture input ports");
|
||||
else
|
||||
veejay_msg(VEEJAY_MSG_WARNING,"[AUDIO] Jack audio playback started without capture input ports");
|
||||
|
||||
return 1;
|
||||
#else
|
||||
veejay_msg(VEEJAY_MSG_WARNING, "[AUDIO] Jack support not compiled in (no audio)");
|
||||
if(!info || !el)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_JACK
|
||||
if(el->has_audio && !vj_perform_audio_params_valid(el)) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING, "[AUDIO] Embedded audio stream has invalid parameters; audio playback disabled");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
const int silent_output = !el->has_audio;
|
||||
int saved_has_audio = el->has_audio;
|
||||
|
||||
if(silent_output) {
|
||||
if(!vj_perform_prepare_silence_audio_params(el)) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING, "[AUDIO] Unable to prepare silent playback parameters");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(info->current_edit_list && info->current_edit_list != el)
|
||||
vj_perform_prepare_silence_audio_params(info->current_edit_list);
|
||||
|
||||
veejay_msg(VEEJAY_MSG_INFO,
|
||||
"[AUDIO] No embedded audio stream; starting JACK silence output (%ld Hz, %d channels, %d bit)",
|
||||
(long)el->audio_rate,
|
||||
el->audio_chans,
|
||||
el->audio_bits);
|
||||
el->has_audio = 1;
|
||||
}
|
||||
|
||||
vj_jack_initialize();
|
||||
|
||||
int res = vj_jack_init_duplex(el);
|
||||
|
||||
if( res <= 0 ) {
|
||||
veejay_msg(VEEJAY_MSG_WARNING,
|
||||
"[AUDIO] Jack duplex start failed; falling back to playback-only mode");
|
||||
|
||||
vj_jack_initialize();
|
||||
res = vj_jack_init(el);
|
||||
}
|
||||
|
||||
if(silent_output)
|
||||
el->has_audio = saved_has_audio;
|
||||
|
||||
if( res <= 0 ) {
|
||||
veejay_msg(0, "[AUDIO] Audio playback disabled");
|
||||
info->audio = NO_AUDIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( res == 2 )
|
||||
{
|
||||
vj_jack_stop();
|
||||
info->audio = NO_AUDIO;
|
||||
veejay_msg(VEEJAY_MSG_ERROR,"Please run jackd with a sample rate of %ld",(long)el->audio_rate );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(vj_jack_has_input())
|
||||
veejay_msg(VEEJAY_MSG_DEBUG,"[AUDIO] Jack audio playback started with capture input ports");
|
||||
else
|
||||
veejay_msg(VEEJAY_MSG_WARNING,"[AUDIO] Jack audio playback started without capture input ports");
|
||||
|
||||
return 1;
|
||||
#else
|
||||
if(el->has_audio)
|
||||
veejay_msg(VEEJAY_MSG_WARNING, "[AUDIO] Jack support not compiled in (no audio)");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void vj_perform_audio_stop(veejay_t * info)
|
||||
{
|
||||
if (info->edit_list->has_audio) {
|
||||
if(!info)
|
||||
return;
|
||||
|
||||
if (info->audio == AUDIO_PLAY || (info->edit_list && info->edit_list->has_audio)) {
|
||||
#ifdef HAVE_JACK
|
||||
vj_jack_stop();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user