philippe44 преди 5 години
родител
ревизия
b53c14a2b5
променени са 4 файла, в които са добавени 76 реда и са изтрити 35 реда
  1. 2 2
      main/output.c
  2. 61 27
      main/output_dac.c
  3. 12 5
      main/output_pack.c
  4. 1 1
      main/squeezelite.h

+ 2 - 2
main/output.c

@@ -48,7 +48,7 @@ frames_t _output_frames(frames_t avail) {
 	frames_t frames, size;
 	bool silence;
 	
-	s32_t cross_gain_in = 0, cross_gain_out = 0; s32_t *cross_ptr = NULL;
+	s32_t cross_gain_in = 0, cross_gain_out = 0; ISAMPLE_T *cross_ptr = NULL;
 	
 	s32_t gainL = output.current_replay_gain ? gain(output.gainL, output.current_replay_gain) : output.gainL;
 	s32_t gainR = output.current_replay_gain ? gain(output.gainR, output.current_replay_gain) : output.gainR;
@@ -242,7 +242,7 @@ frames_t _output_frames(frames_t avail) {
 							gainL = output.gainL;
 							gainR = output.gainR;
 							if (output.invert) { gainL = -gainL; gainR = -gainR; }
-							cross_ptr = (s32_t *)(output.fade_end + cur_f * BYTES_PER_FRAME);
+							cross_ptr = (ISAMPLE_T *)(output.fade_end + cur_f * BYTES_PER_FRAME);
 						} else {
 							LOG_INFO("unable to continue crossfade - too few samples");
 							output.fade = FADE_INACTIVE;

+ 61 - 27
main/output_dac.c

@@ -10,6 +10,10 @@ static bool running = true;
 extern struct outputstate output;
 extern struct buffer *outputbuf;
 
+#if REPACK && BYTES_PER_FRAMES == 4
+#error "REPACK is not compatible with BYTES_PER_FRAME=4"
+#endif
+
 #define LOCK   mutex_lock(outputbuf->mutex)
 #define UNLOCK mutex_unlock(outputbuf->mutex)
 
@@ -17,33 +21,34 @@ extern struct buffer *outputbuf;
 
 extern u8_t *silencebuf;
 
-// buffer to hold output data so we can block on writing outside of output lock, allocated on init
-static u8_t *buf;
-static unsigned buffill;
+static u8_t *optr;
 static int bytes_per_frame;
 static thread_type thread;
 
 static int _dac_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
-								s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr);
+								s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
 static void *output_thread();
 
-void set_volume(unsigned left, unsigned right) {}
+void set_volume(unsigned left, unsigned right) {
+	LOG_DEBUG("setting internal gain left: %u right: %u", left, right);
+	LOCK;
+	output.gainL = left;
+	output.gainR = right;
+	UNLOCK;
+}
 
 void output_init_dac(log_level level, unsigned output_buf_size, char *params, unsigned rates[], unsigned rate_delay, unsigned idle) {
 	loglevel = level;
 
 	LOG_INFO("init output DAC");
-
-	buf = malloc(FRAME_BLOCK * BYTES_PER_FRAME);
-	if (!buf) {
-		LOG_ERROR("unable to malloc buf");
-		return;
-	}
-	buffill = 0;
-
+	
 	memset(&output, 0, sizeof(output));
 
+#if BYTES_PER_FRAME == 4
+	output.format = S16_LE;
+#else 
 	output.format = S32_LE;
+#endif	
 	output.start_frames = FRAME_BLOCK * 2;
 	output.write_cb = &_dac_write_frames;
 	output.rate_delay = rate_delay;
@@ -82,38 +87,65 @@ void output_close_dac(void) {
 	running = false;
 	UNLOCK;
 
-	free(buf);
-
 	output_close_common();
 }
 
 static int _dac_write_frames(frames_t out_frames, bool silence, s32_t gainL, s32_t gainR,
-								s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr) {
+								s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
 
 	u8_t *obuf;
-
+	
 	if (!silence) {
 		
 		if (output.fade == FADE_ACTIVE && output.fade_dir == FADE_CROSS && *cross_ptr) {
 			_apply_cross(outputbuf, out_frames, cross_gain_in, cross_gain_out, cross_ptr);
 		}
-
-		obuf = outputbuf->readp;
+		
+#if !REPACK
+		if (gainL != FIXED_ONE || gainR!= FIXED_ONE) {
+			_apply_gain(outputbuf, out_frames, gainL, gainR);
+		}
+			
+		IF_DSD(
+		if (output.outfmt == DOP) {
+				update_dop((u32_t *) outputbuf->readp, out_frames, output.invert);
+			} else if (output.outfmt != PCM && output.invert)
+				dsd_invert((u32_t *) outputbuf->readp, out_frames);
+		)
+		
+		memcpy(optr, outputbuf->readp, out_frames * BYTES_PER_FRAME);
+#else
+		obuf = outputbuf->readp;	
+#endif		
 
 	} else {
 
 		obuf = silencebuf;
+#if !REPACK
+		IF_DSD(
+			if (output.outfmt != PCM) {
+				obuf = silencebuf_dsd;
+				update_dop((u32_t *) obuf, out_frames, false); // don't invert silence
+			}
+		)
+
+		memcpy(optr, obuf, out_frames * BYTES_PER_FRAME);
+#endif		
 	}
 
-	_scale_and_pack_frames(buf + buffill * bytes_per_frame, (s32_t *)(void *)obuf, out_frames, gainL, gainR, output.format);
-
-	buffill += out_frames;
+#if REPACK
+	_scale_and_pack_frames(optr, (s32_t *)(void *)obuf, out_frames, gainL, gainR, output.format);
+#endif	
 
 	return (int)out_frames;
 }
 
 static void *output_thread() {
+	// buffer to hold output data so we can block on writing outside of output lock, allocated on init
+	u8_t *obuf = malloc(FRAME_BLOCK * BYTES_PER_FRAME);
+	unsigned frames = 0;
 
+#if REPACK
 	LOCK;
 
 	switch (output.format) {
@@ -129,6 +161,7 @@ static void *output_thread() {
 	}
 
 	UNLOCK;
+#endif	
 
 	while (running) {
 
@@ -144,14 +177,15 @@ static void *output_thread() {
 		output.updated = gettime_ms();
 		output.frames_played_dmp = output.frames_played;
 
-		_output_frames(FRAME_BLOCK);
+		optr = obuf + frames * bytes_per_frame;
+		frames += _output_frames(FRAME_BLOCK);
 		
 		UNLOCK;
 
-		if (buffill) {
-			// do something ...
-			usleep((buffill * 1000 * 1000) / output.current_sample_rate);			
-			buffill = 0;
+		if (frames) {
+			// do something with some of these frames...
+			usleep((frames * 1000 * 1000) / output.current_sample_rate);			
+			frames = 0;
 		} else {
 			usleep((FRAME_BLOCK * 1000 * 1000) / output.current_sample_rate);
 		}	

+ 12 - 5
main/output_pack.c

@@ -23,8 +23,14 @@
 
 #include "squeezelite.h"
 
+#if BYTES_PER_FRAM == 4
+#define MAX_VAL16 0x7fffffffLL
 #define MAX_SCALESAMPLE 0x7fffffffffffLL
 #define MIN_SCALESAMPLE -MAX_SCALESAMPLE
+#else
+#define MAX_SCALESAMPLE 0x7fffffffffffLL
+#define MIN_SCALESAMPLE -MAX_SCALESAMPLE
+#endif
 
 // inlining these on windows prevents them being linkable...
 #if !WIN
@@ -338,11 +344,11 @@ void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_
 #if !WIN
 inline 
 #endif
-void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr) {
-	s32_t *ptr = (s32_t *)(void *)outputbuf->readp;
+void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr) {
+	ISAMPLE_T *ptr = (ISAMPLE_T *)(void *)outputbuf->readp;
 	frames_t count = out_frames * 2;
 	while (count--) {
-		if (*cross_ptr > (s32_t *)outputbuf->wrap) {
+		if (*cross_ptr > (ISAMPLE_T *)outputbuf->wrap) {
 			*cross_ptr -= outputbuf->size / BYTES_PER_FRAME * 2;
 		}
 		*ptr = gain(cross_gain_out, *ptr) + gain(cross_gain_in, **cross_ptr);
@@ -354,8 +360,8 @@ void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gai
 inline 
 #endif
 void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR) {
-	s32_t *ptrL = (s32_t *)(void *)outputbuf->readp;
-	s32_t *ptrR = (s32_t *)(void *)outputbuf->readp + 1;
+	ISAMPLE_T *ptrL = (ISAMPLE_T *)(void *)outputbuf->readp;
+	ISAMPLE_T *ptrR = (ISAMPLE_T *)(void *)outputbuf->readp + 1;
 	while (count--) {
 		*ptrL = gain(gainL, *ptrL);
 		*ptrR = gain(gainR, *ptrR);
@@ -363,3 +369,4 @@ void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t ga
 		ptrR += 2;
 	}
 }
+

+ 1 - 1
main/squeezelite.h

@@ -733,7 +733,7 @@ void output_close_stdout(void);
 
 // output_pack.c
 void _scale_and_pack_frames(void *outputptr, s32_t *inputptr, frames_t cnt, s32_t gainL, s32_t gainR, output_format format);
-void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, s32_t **cross_ptr);
+void _apply_cross(struct buffer *outputbuf, frames_t out_frames, s32_t cross_gain_in, s32_t cross_gain_out, ISAMPLE_T **cross_ptr);
 void _apply_gain(struct buffer *outputbuf, frames_t count, s32_t gainL, s32_t gainR);
 s32_t gain(s32_t gain, s32_t sample);
 s32_t to_gain(float f);