At Sun, 1 Aug 2010 01:32:23 +0200, Manuel Lauss wrote: > > > > >> Is there a way to insert an initial playback delay? Under linux, the > > > >> first 2-2.5 seconds > > > >> of anything played are just silence; on windows audible playback > > > >> starts immediately. > > > > > > > > It's the time for synchronization your digital receiver takes, I guess. > > > > Maybe changing SPDIF status makes it resync, which happens at each > > > > opening / closing the stream. > > > > > > Yes, seems so. I've found a workaround in meantime. > > > > Could you elaborate on the workaround please, so others having this > > issue know it. > > My receiver allows to mix analog and digital inputs; with analog mix > enabled it syncs immediately. Just wondering whether the patch below helps? It's just a proof-of-concept, and it's not safe for multiple streams. If this works, we can move on the improvement of the stream assignment. thanks, Takashi --- diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 4d5abbd..45f2bb3 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1181,38 +1181,30 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, int channel_id, int format) { + u32 oldval; + if (!nid) return; snd_printdd("hda_codec_setup_stream: " "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", nid, stream_tag, channel_id, format); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, - (stream_tag << 4) | channel_id); - msleep(1); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); + stream_tag = (stream_tag << 4) | channel_id; + oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); + if (stream_tag != oldval) { + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CHANNEL_STREAMID, stream_tag); + } + oldval = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_STREAM_FORMAT, 0); + if (format != oldval) { + msleep(1); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, + format); + } } EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); -/** - * snd_hda_codec_cleanup_stream - clean up the codec for closing - * @codec: the CODEC to clean up - * @nid: the NID to clean up - */ -void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) -{ - if (!nid) - return; - - snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); -#if 0 /* keep the format */ - msleep(1); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); -#endif -} -EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); - /* * amp access functions */ diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index a115c0c..61e177d 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -927,7 +927,10 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec); void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, int channel_id, int format); -void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); +/*void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid);*/ +static inline void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) {} + + unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, unsigned int format, _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel