diff options
author | waker <wakeroid@gmail.com> | 2010-12-12 20:36:37 +0100 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2010-12-12 20:36:37 +0100 |
commit | 8f6c03d93af6501c960360c77fd7540380e535dc (patch) | |
tree | 4d56f6fbf9dd14bbc219aac4bd435389d20ddb4b | |
parent | a2589162ebec9956ea0c7308194bdc27b8a3868b (diff) |
added softvolume for all supported output formats; moved softvolume from output plugins to streamer
-rw-r--r-- | deadbeef.h | 3 | ||||
-rw-r--r-- | plugins/alsa/alsa.c | 43 | ||||
-rw-r--r-- | plugins/oss/oss.c | 8 | ||||
-rw-r--r-- | streamer.c | 48 |
4 files changed, 53 insertions, 49 deletions
@@ -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 @@ -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; } |