2010-03-15 8 views
6

Digamos que reproduzco un archivo WAV estéreo con 317,520,000 muestras, que es teóricamente 1 hora de duración. Suponiendo que no haya interrupciones en la reproducción, ¿terminará el archivo en exactamente una hora, o hay alguna pequeña variación ocasional en la velocidad de reproducción de modo que sea un poco más o ligeramente menor (en algunos minutos) que una hora ?¿Con qué precisión (en términos de tiempo) Windows reproduce audio?

Estoy tratando de sincronizar la animación con el audio, y estoy usando un System.Diagnostics.Stopwatch para mantener los cuadros que coincidan con el audio. Pero si la velocidad de reproducción de audio WAV en Windows puede variar ligeramente con el tiempo, el audio se desviará de sincronización con la animación impulsada por el cronómetro.

Lo que lleva a una segunda pregunta: parece que un Stopwatch - aunque muy granular y preciso para duraciones cortas - se ejecuta un poco rápido. En mi computadora portátil, una ejecución de Stopwatch durante exactamente 24 horas (medida por la hora del sistema de la computadora y un cronómetro real) muestra un tiempo transcurrido de 24 horas más de aproximadamente 5 segundos (no milisegundos).

¿Es este un problema conocido con Stopwatch? (Una pregunta relacionada sería "¿estoy loco?", Pero puedes intentarlo por ti mismo). Dado su uso como una herramienta de diagnóstico, puedo ver dónde una discrepancia como esta solo aparece cuando se miden duraciones largas, para lo cual la mayoría las personas usarían algo distinto de Stopwatch.

Si tengo mucha suerte, tanto la Stopwatch como la reproducción de audio son impulsadas por el mismo mecanismo subyacente y, por lo tanto, permanecerán sincronizados durante días enteros. ¿Hay alguna posibilidad de que esto sea cierto?

actualización: acabo de hacer los cálculos, y si Stopwatch derivas por 5 segundos de más de 24 horas, esto significa que va a la deriva por 10 milisegundos después de tan sólo 172 segundos. Entonces, en 3 minutos, la animación comenzará a estar perceptiblemente fuera de sincronización.

Estoy experimentando periódicamente (cada 10 segundos más o menos) reiniciando el temporizador de la devolución de llamada waveOutWrite, pero esto no está funcionando porque el siguiente conjunto de eventos del temporizador se compensa con la inexactitud del devolución de llamada pasó a ser. Apesta ser yo.

+0

¿Cómo sabe que su "cronómetro real" no está funcionando un poco lento? –

+0

@Ben S: también sincronizado con un reloj de escritorio (con segundos) y otra PC. Todo tuvo el mismo tiempo de dar o tomar medio segundo, excepto el 'Cronómetro '. Solo probé esto debido a otra pregunta de StackOverflow en la que alguien mencionó que el cronómetro funcionaba aproximadamente 10 segundos cada 24 horas en su PC. Me encantaría ver esto confirmado/refutado por otros. – MusiGenesis

+0

Aquí estaba esa pregunta: http://stackoverflow.com/questions/1416139/how-to-get-timestamp-of-tick-precision-in-net-c – MusiGenesis

Respuesta

0

Larry Osterman dio la respuesta en un comentario:

Fwiw, en Windows el reloj de vídeo es impulsado por el reloj de audio. Si eres de audio renderizado, se obtiene el reloj de audio llamando waveOutGetPosition (puesto que el audio está sincronizado, la posición se corrolated directamente con tiempo). Todas las demás API de reproducción de audio tienen una API "GetPosition" similar que se puede usar para determinar la posición de reproducción de audio .

2

Ningún reloj medirá el tiempo "exactamente", ya que todos los dispositivos físicos tienen algunas variaciones y errores de medición. Esto significa que TODOS los relojes serán demasiado rápidos o demasiado lentos (aunque la cantidad de errores puede diferir enormemente, dependiendo del reloj).

En su caso, la salida de audio se controla con el reloj de la tarjeta de sonido que controla el DAC. No conozco la plataforma .NET, pero asumo que el cronómetro es una especie de temporizador de sistema, lo que significa que es impulsado por un reloj DIFERENTE (el de su placa madre, presumiblemente).

Ahora, en general, dos relojes físicos diferentes NUNCA se ejecutarán exactamente a la misma velocidad, por los motivos descritos anteriormente. De ahí proviene la discrepancia que tienes. Lo mismo sucederá con su animación: puede absolutamente nunca suponer que el reloj del sistema y la tarjeta de sonido del reloj DAC son iguales - ¡serán diferentes!

Esto significa que si desea mantener sincronizadas dos transmisiones (video y audio), deben estar controladas por el mismo reloj. Como no puede cambiar el reloj que impulsa su tarjeta de sonido, es una buena opción sincronizar todo con la tarjeta de sonido.

+0

Creo que tiene toda la razón en que la velocidad de audio sería impulsada por el chip en la tarjeta de sonido, y no hay manera de que el cronómetro controle el cronómetro. El problema con el que me encontré sincronizando con la tarjeta de sonido es que la API que estoy usando (waveOutOpen y waveOutWrite) se comunica a la aplicación que llama a través de mensajes, por lo que aunque estos eventos generalmente se sincronizan con el audio, se cronometran de forma tan irregular que la animación es notablemente entrecortada (tuve que cambiar a usar Cronómetro para suavizar la animación). – MusiGenesis

+0

Básicamente, Stopwatch es lo suficientemente preciso para una animación fluida, pero finalmente se desincroniza con la música. Las devoluciones de llamada de waveOut permanecen sincronizadas para siempre, pero no son lo suficientemente fluidas para la animación. Necesito encontrar alguna manera de combinar los dos, como usar las devoluciones de llamadas para ajustar periódicamente el cronómetro. – MusiGenesis

+1

FWIW, en Windows, el reloj de video funciona con el reloj de audio. Si estás renderizando audio, obtienes el reloj de audio llamando a waveOutGetPosition (ya que el audio es isócrono, la posición se corrige directamente con el tiempo). Todas las demás API de reproducción de audio tienen una API similar "GetPosition" que se puede usar para determinar la posición de reproducción de audio. –

Cuestiones relacionadas