1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
/* Effects.cpp - Various effects implementations, needs a cleanup
* Copyright (C) 1998-2002 Andy Lo A Foe <andy@loafoe.com>
*
* This file is part of AlsaPlayer.
*
* AlsaPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* AlsaPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "Effects.h"
static char buf[DELAY_BUF_SIZE];
static char cont_buf[MAX_CHUNK];
static int head = 0;
void init_effects()
{
memset(buf, 0, sizeof(buf));
}
extern "C" {
void clear_buffer(void)
{
memset(buf, 0, sizeof(buf));
}
}
void buffer_effect(void *buffer, int size)
{
int tmp;
char *input = (char *)buffer;
if ((head + size) > DELAY_BUF_SIZE) {
memcpy(buf + head, input, DELAY_BUF_SIZE - head);
tmp = (DELAY_BUF_SIZE - head);
memcpy(buf, (input + tmp), size - tmp);
head = size - tmp;
} else {
memcpy(buf + head, input, size);
head += size;
}
}
void echo_effect32(void *buffer, int size, int delay, int vol)
{
int tail;
int tmp;
int gap = ((44100 * 2 * 2) / 1000) * delay;
if (size % 4) {
printf("Warning, size is not a multiple of 4\n");
}
tail = (head - gap) < 0 ?
DELAY_BUF_SIZE + (head - gap) : head - gap;
short *s = (short *)(buf + tail);
short *d = (short *)buffer;
int i, v;
if ((tail + size) > DELAY_BUF_SIZE) {
tmp = DELAY_BUF_SIZE - tail;
for (i = 0; i < tmp / 2; i++) {
v = ((*(s++) * vol)/100) + *d;
*(d++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
}
tmp = size - (DELAY_BUF_SIZE - tail);
s = (short *)buf;
for (i = 0; i < tmp / 2; i++) {
v = ((*(s++) * vol)/100) + *d;
*(d++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
}
} else {
for (i = 0; i < size / 2; i++) {
v = ((*(s++) * vol)/100) + *d;
*(d++) = (v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
}
}
}
void volume_effect32(void *buffer, int length, float left, float right)
{
short *data = (short *)buffer;
if (right == -100.0) right=left;
for (int i=0; i < length << 1; i+=2) {
int v=(int) ((*(data) * (int)(left * 100)) / 100);
*(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
v=(int) ((*(data) * (int)(right * 100)) / 100);
*(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
}
}
char *delay_feed(int delay_bytes, int max_size)
{
int copy;
int copied = 0;
int use_head = head;
//memset(cont_buf, 0xf, max_size);
#if 1
if ((copy = use_head - delay_bytes) < 0) { // Wraparound to end of buffer
copy = abs(copy);
if (copy <= max_size) {
memcpy(cont_buf, buf + DELAY_BUF_SIZE - copy, copy);
copied+=copy;
memcpy(&cont_buf[copy], buf, max_size - copy);
copied+=(max_size - copy);
} else {
memcpy(cont_buf, buf + DELAY_BUF_SIZE - copy, max_size);
copied+=max_size;
}
//printf("copied = %d\n", copied);
return cont_buf;
}
#else
if ((copy = (use_head - delay_bytes + max_size)) > DELAY_BUF_SIZE) {
//printf("%d\n", DELAY_BUF_SIZE - (use_head - delay_bytes));
memcpy(cont_buf, &buf[use_head - delay_bytes], DELAY_BUF_SIZE - (use_head - delay_bytes));
memcpy(cont_buf + DELAY_BUF_SIZE - copy, buf, max_size - (DELAY_BUF_SIZE - copy));
return cont_buf;
}
#endif
//memcpy(cont_buf, buf + use_head - delay_bytes, max_size);
return (buf + use_head - delay_bytes);
//return cont_buf;
}
|