Jaroslav Kysela wrote: > > On Mon, 17 Feb 2003, Jaroslaw Sobierski wrote: > > > > > b) sum overflow: we can lower volume of samples before sum; I think that > > > > hardware works in this way, too > > > > > > Here I don't understand you. Suppose we have 3 samples to mix: > > > a = 0x7500 > > > b = 0x7400 > > > c = 0x8300 > > > > > > If you do a + b + c (in this order) you obtain: > > > d=0 > > > d += a -> 7500 > > > d += b -> 0xe900 -> 0x7fff > > > d += c -> 0x02ff > > > > > > while the correct result is 0x6c00. You see? > > > > AFAIK most hardware does not mix by reducing volume before the sum. On the > > contrary, it is usually summed "as is" to a wider register, and often even so > > used. For example, a sound card able to mix 16 chanels of 16 bits would have > > a 16+4 bits or 24 bit register were the channels are added and no saturation > > can occur. In good hardware this would not even be downscaled back to 16 bits, > > but a 24 bit D/A converter would be used instead. In older times (Gravis Ultra > > Sound and I think older SB AWE) this could easily be spotted by the difference > > in supported "hardware" channels and "software" channels. A card with a 32 bit > > sum register and 24 bit DA could support (as above) 16 hardware channels and > > for example 64 software channels (mixed together in quadrouplets to the 16 hw). > > > > In our case, such "solution" would have to affect the whole buffer, meaning > > we would need 3 (or better yet 4) bytes per sample, which would eventually get > > reduced back to 2 bytes on the way out to the sound card. This seems neither > > elegant nor memory efficient but would work, and also solves the "a)" problem > > because we don't need to saturate so an atomic add can be performed on each > > sample. > > Yes, this solution is good. I've though about it, too. Unfortunately, it > adds additional transfers including saturation from the "sum" ring buffer > to the DMA buffer of hardware.
I remember you that the main point of dmix existence is the "direct" part. If we'd need to use an intermediate buffer and a mixing thread, the dmix approach lose our interest. A solution might be to have a shared parallel sw ring buffer where to store the exact value: xadd(sw, *src); do { v = *sw; if (v > 0x7fff) s = 0x7fff; else if (v < -0x8000) s = -0x8000; else s = v; *hw = v; } while (unlikely(v != *sw)); This should solve also the atomicity update. Comments? -- Abramo Bagnara mailto:[EMAIL PROTECTED] Opera Unica Phone: +39.546.656023 Via Emilia Interna, 140 48014 Castel Bolognese (RA) - Italy ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Alsa-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-devel