- fix memory leak after "kldunload snd_ak452x.ko"

- fix "No sound in KDE":
  The problem is related to the implementation of Envy24(1712) hardware
  mixer support in the driver. Envy24(1712) has very precise 36bit wide
  hardware mixer, which is superior that vchans (software sound mixer in
  the kernel). The driver supports Envy24(1712) hardware mixer, so up to
  10 channels (5 stereo pairs) can be playback simultaneously.
  However, there are problems with the implementation of Envy24(1712)
  hardware mixer support in the driver, one of them is the problem with
  "no sound in KDE":
      When playing back several channels simultaneously and
      stoping one of the channels, sound starts to stutter and
      plays at very low speed.
  Another problem is:
      Playing back simultaneously more than one 24bit/32bit
      sound file or 16bit sound file and 24bit/32bit sound
      file doesn't work as expected.

Submitted by:	"Konstantin Dimitrov" <kosio.dimitrov@gmail.com>
This commit is contained in:
netchild 2006-07-28 18:06:39 +00:00
parent 02d00eff20
commit 34c424c364
2 changed files with 26 additions and 10 deletions

View File

@ -781,9 +781,9 @@ envy24_delta_ak4524_create(device_t dev, void *info, int dir, int num)
if (buff == NULL)
return NULL;
if (dir == PCMDIR_PLAY && sc->adc[num] != NULL)
if (dir == PCMDIR_REC && sc->adc[num] != NULL)
buff->info = ((struct envy24_delta_ak4524_codec *)sc->adc[num])->info;
else if (dir == PCMDIR_REC && sc->dac[num] != NULL)
else if (dir == PCMDIR_PLAY && sc->dac[num] != NULL)
buff->info = ((struct envy24_delta_ak4524_codec *)sc->dac[num])->info;
else
buff->info = ak452x_create(dev, buff, num, envy24_delta_ak4524_ctl);
@ -810,11 +810,11 @@ envy24_delta_ak4524_destroy(void *codec)
#endif
if (ptr->dir == PCMDIR_PLAY) {
if (ptr->parent->adc[ptr->num] == NULL)
if (ptr->parent->adc[ptr->num] != NULL)
ak452x_destroy(ptr->info);
}
else {
if (ptr->parent->dac[ptr->num] == NULL)
if (ptr->parent->dac[ptr->num] != NULL)
ak452x_destroy(ptr->info);
}
@ -1591,9 +1591,9 @@ envy24chan_trigger(kobj_t obj, void *data, int go)
struct sc_info *sc = ch->parent;
u_int32_t ptr;
int slot;
#if 0
int i;
#if(0)
device_printf(sc->dev, "envy24chan_trigger(obj, data, %d)\n", go);
#endif
snd_mtxlock(sc->lock);
@ -1667,6 +1667,7 @@ envy24chan_trigger(kobj_t obj, void *data, int go)
envy24_stop(sc, ch->dir);
sc->intr[slot] = 0;
}
#if 0
else if (ch->blk == sc->blk[slot]) {
sc->blk[slot] = ENVY24_SAMPLE_NUM / 2;
for (i = 0; i < ENVY24_CHAN_NUM; i++) {
@ -1678,6 +1679,7 @@ envy24chan_trigger(kobj_t obj, void *data, int go)
if (ch->blk != sc->blk[slot])
envy24_updintr(sc, ch->dir);
}
#endif
break;
}
snd_mtxunlock(sc->lock);
@ -2432,6 +2434,12 @@ bad:
envy24_dmafree(sc);
if (sc->dmat)
bus_dma_tag_destroy(sc->dmat);
if (sc->cfg->codec->destroy != NULL) {
for (i = 0; i < sc->adcn; i++)
sc->cfg->codec->destroy(sc->adc[i]);
for (i = 0; i < sc->dacn; i++)
sc->cfg->codec->destroy(sc->dac[i]);
}
envy24_cfgfree(sc->cfg);
if (sc->cs)
bus_release_resource(dev, SYS_RES_IOPORT, sc->csid, sc->cs);

View File

@ -781,9 +781,9 @@ envy24_delta_ak4524_create(device_t dev, void *info, int dir, int num)
if (buff == NULL)
return NULL;
if (dir == PCMDIR_PLAY && sc->adc[num] != NULL)
if (dir == PCMDIR_REC && sc->adc[num] != NULL)
buff->info = ((struct envy24_delta_ak4524_codec *)sc->adc[num])->info;
else if (dir == PCMDIR_REC && sc->dac[num] != NULL)
else if (dir == PCMDIR_PLAY && sc->dac[num] != NULL)
buff->info = ((struct envy24_delta_ak4524_codec *)sc->dac[num])->info;
else
buff->info = ak452x_create(dev, buff, num, envy24_delta_ak4524_ctl);
@ -810,11 +810,11 @@ envy24_delta_ak4524_destroy(void *codec)
#endif
if (ptr->dir == PCMDIR_PLAY) {
if (ptr->parent->adc[ptr->num] == NULL)
if (ptr->parent->adc[ptr->num] != NULL)
ak452x_destroy(ptr->info);
}
else {
if (ptr->parent->dac[ptr->num] == NULL)
if (ptr->parent->dac[ptr->num] != NULL)
ak452x_destroy(ptr->info);
}
@ -1591,9 +1591,9 @@ envy24chan_trigger(kobj_t obj, void *data, int go)
struct sc_info *sc = ch->parent;
u_int32_t ptr;
int slot;
#if 0
int i;
#if(0)
device_printf(sc->dev, "envy24chan_trigger(obj, data, %d)\n", go);
#endif
snd_mtxlock(sc->lock);
@ -1667,6 +1667,7 @@ envy24chan_trigger(kobj_t obj, void *data, int go)
envy24_stop(sc, ch->dir);
sc->intr[slot] = 0;
}
#if 0
else if (ch->blk == sc->blk[slot]) {
sc->blk[slot] = ENVY24_SAMPLE_NUM / 2;
for (i = 0; i < ENVY24_CHAN_NUM; i++) {
@ -1678,6 +1679,7 @@ envy24chan_trigger(kobj_t obj, void *data, int go)
if (ch->blk != sc->blk[slot])
envy24_updintr(sc, ch->dir);
}
#endif
break;
}
snd_mtxunlock(sc->lock);
@ -2432,6 +2434,12 @@ bad:
envy24_dmafree(sc);
if (sc->dmat)
bus_dma_tag_destroy(sc->dmat);
if (sc->cfg->codec->destroy != NULL) {
for (i = 0; i < sc->adcn; i++)
sc->cfg->codec->destroy(sc->adc[i]);
for (i = 0; i < sc->dacn; i++)
sc->cfg->codec->destroy(sc->dac[i]);
}
envy24_cfgfree(sc->cfg);
if (sc->cs)
bus_release_resource(dev, SYS_RES_IOPORT, sc->csid, sc->cs);