On Fri, 13 May 2011 12:39:43 +0200
Alexandre Ratchov <[email protected]> wrote:
> On Thu, May 12, 2011 at 12:36:43AM +0300, Sviatoslav Chagaev wrote:
> > > >
> > > > So, why is what I'm proposing better than what currently exists:
> > > >
> > > > * Resembles how sound behaves in real world more closely;
> > > > * Doesn't violate the principle of least surprise;
> > > > * No more annoying volume jumps up and down;
> > > > * No need to use the -v option anymore / less stuff to remember / "it
> > > > just works";
> > > > * No more choosing between being annoyed by volume jumps or loosing
> > > > dynamic range.
> > > >
> > >
> > > I guess this works well with your recordings by accident, as it would
> > > with mines. I bet they are pre-divided, so you almost never hit the
> > > ADATA_MIN and ADATA_MAX bundary, and there's almost no clipping, is
> > > it?
> > >
> >
> > Before posting, I tested by playing, I don't remember exactly,
> > either 2 either 3 files simultaneously. And honestly, I didn't notice
> > any distortions. This is probably because of the fact that like you
> > said, it's rare that all the waves have +/-ADATA_UNIT value at a given
> > moment. After reading your replies, I tried playing ~8 files
> > simultaneously and I indeed heard clearly sound distortion.
> >
> > > If so, for such streams you could do:
> > >
> > > int
> > > adata_sadd(int x, int y)
> > > {
> > > return x + y;
> > > }
> > >
> >
> > The ADATA_MIN ADATA_MAX checks are needed because without them, you
> > will start hearing distorions as soon as you play 2 files and this
> > distortion is much worse sounding than the saturation distortion.
> >
>
> While discussing about what defaults are good for what, here's a diff
> I plan to put in soon.
>
> It's to add a switch to make automatic volume changes optional.
> Sometimes I need this when I'm playing pre-scaled streams, or to mix
> streams that fade in / fade out.
>
> -- Alexandre
>
Then the only thing that remains -- is to add clipping in mix_badd().
This will give aucat all the bits and pieces to meet the requirements
of all kinds of users.
(Tested on i386 and amd64 with 16 and 24 bits ADATA)
Index: aproc.c
===================================================================
RCS file: /cvs/src/usr.bin/aucat/aproc.c,v
retrieving revision 1.64
diff -u -p -r1.64 aproc.c
--- aproc.c 28 Apr 2011 07:20:03 -0000 1.64
+++ aproc.c 14 May 2011 14:42:58 -0000
@@ -617,6 +617,11 @@ mix_badd(struct abuf *ibuf, struct abuf
unsigned i, j, cc, istart, inext, onext, ostart;
unsigned scount, icount, ocount;
int vol;
+#if ADATA_BITS <= 16
+ register int data;
+#else
+ register long long data;
+#endif
#ifdef DEBUG
if (debug_level >= 4) {
@@ -673,7 +678,13 @@ mix_badd(struct abuf *ibuf, struct abuf
idata += istart;
for (i = scount; i > 0; i--) {
for (j = cc; j > 0; j--) {
- *odata += ADATA_MUL(*idata, vol);
+ data = *odata;
+ data += ADATA_MUL(*idata, vol);
+ if (data < -ADATA_UNIT)
+ data = -ADATA_UNIT;
+ else if (data > (ADATA_UNIT-2))
+ data = (ADATA_UNIT-2);
+ *odata = (adata_t) data;
idata++;
odata++;
}