summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2010-12-12 20:36:37 +0100
committerGravatar waker <wakeroid@gmail.com>2010-12-12 20:36:37 +0100
commit8f6c03d93af6501c960360c77fd7540380e535dc (patch)
tree4d56f6fbf9dd14bbc219aac4bd435389d20ddb4b
parenta2589162ebec9956ea0c7308194bdc27b8a3868b (diff)
added softvolume for all supported output formats; moved softvolume from output plugins to streamer
-rw-r--r--deadbeef.h3
-rw-r--r--plugins/alsa/alsa.c43
-rw-r--r--plugins/oss/oss.c8
-rw-r--r--streamer.c48
4 files changed, 53 insertions, 49 deletions
diff --git a/deadbeef.h b/deadbeef.h
index bd1655c7..02401f5e 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -749,6 +749,9 @@ typedef struct DB_output_s {
// parameters of current output
ddb_waveformat_t fmt;
+
+ // set to 1 if volume control is done internally by plugin
+ int has_volume;
} DB_output_t;
// dsp plugin
diff --git a/plugins/alsa/alsa.c b/plugins/alsa/alsa.c
index 755981fa..68981512 100644
--- a/plugins/alsa/alsa.c
+++ b/plugins/alsa/alsa.c
@@ -615,48 +615,7 @@ palsa_thread (void *context) {
static int
palsa_callback (char *stream, int len) {
- int bytesread = deadbeef->streamer_read (stream, len);
-
-// FIXME: move volume control to streamer_read for copy optimization
-#if 0
- int16_t vol[4];
- vol[0] = volume_get_amp () * 255; // that will be extra 8 bits
- // pack 4 times
- vol[1] = vol[2] = vol[3] = vol[0];
-
- // apply volume with mmx
- __asm__ volatile(
- " mov %0, %%ecx\n\t"
- " shr $4, %%ecx\n\t"
- " mov %1, %%eax\n\t"
- " movq %2, %mm1\n\t"
- "1:\n\t"
- " movq [%%eax], %mm0\n\t"
- " movq %mm0, %mm2\n\t"
- " movq %mm0, %mm3\n\t"
- " pmullw %mm1, %mm2\n\t"
- " pmulhw %mm1, %mm3\n\t"
- " psrlw $8, %mm2\n\t" // discard lowest 8 bits
- " psllw $8, %mm3\n\t" // shift left 8 lsbs of hiwords
- " por %mm3, %mm2\n\t" // OR them together
- " movq %mm3, [%%eax]\n\t" // load back to memory
- " add $8, %%eax\n\t"
- " dec %%ecx\n\t"
- " jnz 1b\n\t"
- :
- : "r"(len), "r"(stream), "r"(vol)
- : "%ecx", "%eax"
- );
-
-#else
- if (plugin.fmt.bps == 16) {
- int16_t ivolume = deadbeef->volume_get_amp () * 1000;
- for (int i = 0; i < bytesread/2; i++) {
- ((int16_t*)stream)[i] = (int16_t)(((int32_t)(((int16_t*)stream)[i])) * ivolume / 1000);
- }
- }
-#endif
- return bytesread;
+ return deadbeef->streamer_read (stream, len);
}
static int
diff --git a/plugins/oss/oss.c b/plugins/oss/oss.c
index 0f837c43..b78a2290 100644
--- a/plugins/oss/oss.c
+++ b/plugins/oss/oss.c
@@ -278,13 +278,7 @@ oss_thread (void *context) {
static int
oss_callback (char *stream, int len) {
- int bytesread = deadbeef->streamer_read (stream, len);
- int16_t ivolume = deadbeef->volume_get_amp () * 1000;
- for (int i = 0; i < bytesread/2; i++) {
- ((int16_t*)stream)[i] = (int16_t)(((int32_t)(((int16_t*)stream)[i])) * ivolume / 1000);
- }
-
- return bytesread;
+ return deadbeef->streamer_read (stream, len);
}
static int
diff --git a/streamer.c b/streamer.c
index a6f0ff8c..861e39a2 100644
--- a/streamer.c
+++ b/streamer.c
@@ -1511,6 +1511,54 @@ streamer_read (char *bytes, int size) {
int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
printf ("streamer_read took %d ms\n", ms);
#endif
+
+ if (!output->has_volume) {
+ char *stream = bytes;
+ int bytesread = sz;
+ if (output->fmt.bps == 16) {
+ int16_t ivolume = volume_get_amp () * 1000;
+ for (int i = 0; i < bytesread/2; i++) {
+ int16_t sample = *((int16_t*)stream);
+ *((int16_t*)stream) = (int16_t)(((int32_t)sample) * ivolume / 1000);
+ stream += 2;
+ }
+ }
+ else if (output->fmt.bps == 8) {
+ int16_t ivolume = volume_get_amp () * 255;
+ for (int i = 0; i < bytesread; i++) {
+ *stream = (int8_t)(((int32_t)(*stream)) * ivolume / 1000);
+ stream++;
+ }
+ }
+ else if (output->fmt.bps == 24) {
+ int16_t ivolume = volume_get_amp () * 1000;
+ for (int i = 0; i < bytesread/3; i++) {
+ int32_t sample = ((unsigned char)stream[0]) | ((unsigned char)stream[1]<<8) | (stream[2]<<16);
+ int32_t newsample = (int64_t)sample * ivolume / 1000;
+ stream[0] = (newsample&0x0000ff);
+ stream[1] = (newsample&0x00ff00)>>8;
+ stream[2] = (newsample&0xff0000)>>16;
+ stream += 3;
+ }
+ }
+ else if (output->fmt.bps == 32 && !output->fmt.is_float) {
+ int16_t ivolume = volume_get_amp () * 1000;
+ for (int i = 0; i < bytesread/4; i++) {
+ int32_t sample = *((int32_t*)stream);
+ int32_t newsample = (int64_t)sample * ivolume / 1000;
+ *((int32_t*)stream) = newsample;
+ stream += 4;
+ }
+ }
+ else if (output->fmt.bps == 32 && output->fmt.is_float) {
+ float fvolume = volume_get_amp ();
+ for (int i = 0; i < bytesread/4; i++) {
+ *((float*)stream) = (*((float*)stream)) * fvolume;
+ stream += 4;
+ }
+ }
+ }
+
return sz;
}