Estreno nuevo subforo y avances emulador Spectrum dcrespo

Avatar de Usuario
zx81
Mensajes: 469
Registrado: 23 Feb 2013 21:31
Agradecido : 87 veces
Agradecimiento recibido: 223 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor zx81 » 20 Jun 2022 22:18

Último mensaje de la página anterior:

El sonido, el puñetero sonido... el tema da como para escribir un libro y/o cortarse las venas.

Lo que veo ahí no me hace presagiar nada bueno. Siento ser tan claro y directo, pero es lo que pienso. A riesgo de acabar en "tocho inside", haré las siguientes consideraciones:

1.- Una frecuencia de 48 kHz parece muy chachi, pero es innecesaria. Serviría, en principio, para poder reproducir señales de hasta 24 kHz, 2000 Hz por encima del rango audible modelo "lush life", que casi nadie tiene. El beeper del Spectrum fijo que no llegaba muy por encima de 8 Khz, y posiblemente ni eso. O sea, con una frecuencia de 32 kHz se va más que sobrado.

2.- Una cosa muy puñetera del sonido es que se deben generar la cantidad de muestras necesaria, ni muchas, ni pocas. Eso de calcular a ojímetro un sample cada 73 t-states, produce una frecuencia de sampleo de 47.945,2 Hz. Mal asunto ese. Ya de por sí, es casi imposible cuadrar un número de muestras exactas por frame aunque, en el peor de los casos, al menos cuadrará una vez por segundo, o debería. Y si no cuadra, se oye, os aseguro que se oye, o más bien se sufre. Nada de descartar cachitos, por pequeños que sean. 47945,2 / 50 = 958,904 samples por cuadro y lo que hay detrás de la coma no se puede descartar, que es casi un sample completo. Ese "if (audioCnt >= 73)" me pone los pelos de picos pardos.

3.- Para usar menos CPU, se puede hacer al contrario, contar los ciclos transcurridos entre dos cambios del bit de beeper (falso, también es necesario el bit de mic, pero por simplificar) y generar un número de muestras proporcional a los ciclos pasados entre cambios. Salvo voces polifónicas, muchas melodías dejan pasar cientos de t-states entre cambios de estado del bit del beeper. Vuelvo a insistir vehementemente en que no es posible de ningún modo descartar o añadir nada, porque luego se escucha todo. Lo "mejor" es cuando empieza a producirse aliasing, la cacofonía puede llegar a ser indescriptible.

4.- Cuantos más filtros pongas, da igual que sean filtros FIR o IIR, menos suena a Spectrum. El sonido del ordenador es sucio, de un sucio imposible de replicar ni siquiera por un SID de C64, ya quisieran, ya. Determinadas melodías tienen armónicos en el original, y no vale comprobar contra otro emulador, hay que escuchar el original para hacerse una idea real de lo que se debería oír. Por experiencia sé que emular a otro emulador, no es buena idea.

Lo de las pesadillas para cuadrar los samples generados por el beeper, con los generados por el AY, lo dejo para otro día.
Cuando utilizo una palabra, esa palabra significa, exactamente, lo que yo quiero que signifique. Ni más, ni menos.
Humpty Dumpty

Empieza a jugar sin tener que compilar: Emulador JSpeccy
ZX Spectrum bare-metal para Raspberry PI ZXBaremulator

Avatar de Usuario
Eremus
Mensajes: 43
Registrado: 01 May 2022 18:10
Agradecido : 70 veces
Agradecimiento recibido: 75 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor Eremus » 21 Jun 2022 13:38

dcrespo3d escribió:Parece que lo tienes mucho más claro que yo, sigue explorando ese camino. Sólo me puse a mirarlo porque ví que en tu lista de prioridades esto del sonido lo tenías lo último -grin

-sorry Me dio por echarle un vistazo al asunto y, para cuando quise darme cuenta, ya era mi único propósito en la vida -grin

dcrespo3d escribió:No tiene sentido que estemos los dos trabajando en lo mismo en paralelo ...

Toda la razón. En adelante procuraré que nos coordinemos mejor que cuesta poco y redundará en un mejor emu para todos. :)

zx81 escribió:El sonido, el puñetero sonido... el tema da como para escribir un libro y/o cortarse las venas.

Yo me las voy a dejar largas por ahora pero he estado considerando la opción -rofl

zx81 escribió:Lo que veo ahí no me hace presagiar nada bueno. Siento ser tan claro y directo, pero es lo que pienso.

Tranquilo hombre ¡Que no "panda el cunico"! Lo que ves ahi es "guarreo" puro y duro para ir probando cosas e ir testando conceptos y posibilidades (De hecho hasta me he dado cuenta que hay una línea mal puesta). Realmente, las piezas del puzzle ya las tenemos: procesador, pantalla y sonido funcionan y se sincronizan bien. El problema ahora es que las tres versiones actuales de cada pieza juntas superan la capacidad de proceso que tenemos. Con algo mas de potencia de proceso ya estaría concentrandome en otras cuestiones pero la potencia es la que es. Ese es el problema a superar. Igual parece que no pero aun con mis limitaciones y posibles errores, y gracias por supuesto a vuestra ayuda e información, sé lo que me hago :)

zx81 escribió:A riesgo de acabar en "tocho inside", haré las siguientes consideraciones:

"Tocho" -thumbup Esa es la palabra que queria oir de ti ¡Voy a por el bloc de notas!

zx81 escribió:1.- Una frecuencia de 48 kHz parece muy chachi, pero es innecesaria. Serviría, en principio, para poder reproducir señales de hasta 24 kHz, 2000 Hz por encima del rango audible modelo "lush life", que casi nadie tiene. El beeper del Spectrum fijo que no llegaba muy por encima de 8 Khz, y posiblemente ni eso. O sea, con una frecuencia de 32 kHz se va más que sobrado.

Ahí disiento ligeramente. Cuanto mayor sea la frecuencia de muestreo, mas calidad de sonido vamos a obtener ya que, como comentabas en un post anterior, hay juegos o demos que pueden generar sonido cada 40 t-states o menos. Eso son 87360 Hz. Lógicamente, no tengo potencia para muestrear y reproducir a 96 Khz así que, en la versión actual, que ya empieza a sonar muy bien, uso 31200 hz.

zx81 escribió:2.- Una cosa muy puñetera del sonido es que se deben generar la cantidad de muestras necesaria, ni muchas, ni pocas. Eso de calcular a ojímetro un sample cada 73 t-states, produce una frecuencia de sampleo de 47.945,2 Hz. Mal asunto ese. Ya de por sí, es casi imposible cuadrar un número de muestras exactas por frame aunque, en el peor de los casos, al menos cuadrará una vez por segundo, o debería. Y si no cuadra, se oye, os aseguro que se oye, o más bien se sufre. Nada de descartar cachitos, por pequeños que sean. 47945,2 / 50 = 958,904 samples por cuadro y lo que hay detrás de la coma no se puede descartar, que es casi un sample completo. Ese "if (audioCnt >= 73)" me pone los pelos de picos pardos.

Como dije, codigo de prueba y guarreridas varias. Nada que un poquito de Excel no pueda solucionar. Ahora uso 31200 hz que dan 624 muestras exactas a cada frame (siempre he obtenido las mismas muestras a cada frame en todo caso) y ese if ahora termina en un maravilloso 112 que es mucho mas coder-friendly :)

zx81 escribió:3.- Para usar menos CPU, se puede hacer al contrario, contar los ciclos transcurridos entre dos cambios del bit de beeper (falso, también es necesario el bit de mic, pero por simplificar) y generar un número de muestras proporcional a los ciclos pasados entre cambios. Salvo voces polifónicas, muchas melodías dejan pasar cientos de t-states entre cambios de estado del bit del beeper. Vuelvo a insistir vehementemente en que no es posible de ningún modo descartar o añadir nada, porque luego se escucha todo. Lo "mejor" es cuando empieza a producirse aliasing, la cacofonía puede llegar a ser indescriptible.

Esa idea es interesante y puede que la pruebe aunque la captura de muestras, en su versión actual, no tiene un efecto exagerado en el ciclo. El aliasing supongo que me lo he encontrado a determinadas frecuencias. La sinfonia de chirridos y resultados extravagantes que me he metido en vena estas ultimas horas es pa quedarse chalao -rofl

zx81 escribió:4.- Cuantos más filtros pongas, da igual que sean filtros FIR o IIR, menos suena a Spectrum.

Sin problema. La versión actual ya prescinde de filtrados y cálculos innecesarios.

zx81 escribió:Lo de las pesadillas para cuadrar los samples generados por el beeper, con los generados por el AY, lo dejo para otro día.

Mejor, un infierno cada vez por favor -grin

Un saludo y gracias a los dos por vuestros comentarios -thumbup

Respecto a los últimos avances, os cuento:

He creado otra rama que usa una librería de audio que me ha dado resultados mas que interesantes: https://docs.espressif.com/projects/esp ... audio.html

Básicamente, es un driver de sonido a través del DAC, se definen parámetros del stream y se va alimentando al motor de audio. Tiene impacto en el rendimiento como es lógico pero es, hasta el momento, lo que mejor resultado me ha dado. Me ha permitido, además, añadirle control de volumen de 32 niveles al emu (Teclas F9 y F10).

Ahora no hay que usar CPU_PER_INSTRUCTION_TIMING. La temporización ahora mejor con VIDEO_FRAME_TIMING. Asi, si el ciclo de Audio + CPU + Video no supera los 20ms. todo va bien. Cuando se superan se produce buffer underrun y se ensucia el sonido. Si se desactiva el video (con NO_VIDEO en hardconfig.h) y se lanzan cosas como Arkanoid o Zorro, se aprecia que la calidad de sonido no está nada mal.

En resumen: optimizar mas y mas y mas y mas y mas ...

Disponible en: https://github.com/EremusOne/ZX-ESPectr ... audiotest2

Avatar de Usuario
dcrespo3d
Mensajes: 137
Registrado: 04 Nov 2020 08:51
Agradecido : 121 veces
Agradecimiento recibido: 154 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor dcrespo3d » 21 Jun 2022 21:43

Eremus escribió:Respecto a los últimos avances, os cuento:

He creado otra rama que usa una librería de audio que me ha dado resultados mas que interesantes: https://docs.espressif.com/projects/esp ... audio.html

[...]


Hola, lo he probado y ahora la frecuencia es correcta, los tonos suenan con su nota (por lo menos a la frecuencia de muestreo más baja), pero la polifonía pwm se ensucia muchísimo.

La polífonía pwm se genera por transiciones. Si tenemos dos tonos de períodos 7 y 9 por poner un ejemplo...

T7: 00000000011111111100000000011111111100000000011111111100000000011111111100000...
T9: 00000001111111000000011111110000000111111100000001111111000000011111110000000...
RES:00000001100000111100011111101111111011111100011110000011000000011111110011111...


^^^ La polifonía resultante tendrá transiciones donde transicione uno de los dos tonos (o los dos), y sonará similar a una mezcla de los dos tonos.

Por eso, aunque los períodos de los tonos sean relativamente largos (y sus frecuencias bajas) en ocasiones habrá transiciones muy juntas (hay un momento en que hay dos transiciónes juntas (...11111011111...)

Y si submuestreas eso, va a sonar mal (te vas a perder muchas transiciones necesarias de forma pseudoaleatoria). No sabría decir si es exactamente aliasing o si es otra cosa, pero se le parece, aparecen frecuencias que no estarían en el original... :geek:

Convendría conseguir la mayor frecuencia posible. Yo lo he intentado con

// #define ESP_AUDIO_FREQ 89600
// #define ESP_AUDIO_SAMPLES 1792
// #define ESP_AUDIO_TSTATES 39

... pero se arrastra, además de decirme que frecuencia inválida.

Una cosa que no me queda clara, ¿el pwm_audio este funciona en un core aparte?

En la prueba que hice yo el sábado pasado, estoy seguro de que estaba rellenando con la temporización correcta el buffer (lado productor). Creo que lo estaba haciendo mal en el lado consumidor, que creo que se quedaba sin muestras. Pero el la task en el core 0 CPU+Video iba sobrado (< 20ms) y en el core 1 el audio iba reproduciéndose correctamente (con el mismo mecanismo de esperas ajustadas al tiempo esperado, que usé en el task CPU cuando había tasks de CPU y Video en cores aparte). Está en la rama monohilo de mi repo, que es la tuya con un commit extra.
Quizás le podrías echar un vistazo a ver si por ahí se puede mejorar... -please

La división (entera) que hice fue 69888 / 32 tstates = 2184 muestras. Fíjate en el algoritmo de relleno del buffer cómo utiliza desplazamiento >> 5 para dividir entre 32 y determinar cuales muestras tiene que rellenar, cargaba muy poco a la task de CPU...

Otra idea: para oir bien el sonido lo tengo enchufado al PC a través de la interfaz de audio (lleva un previo decente, un Midas) y la grabo con Audacity para estudiar la forma de onda. Aunque lo de la forma de onda es como las radiografías y los médicos, hay que tener el ojo entrenado... -grin

En fin, que le doy la razón a @zx81, esto es un infienno -507
DavidPrograma en YouTube, GitHub

Avatar de Usuario
zx81
Mensajes: 469
Registrado: 23 Feb 2013 21:31
Agradecido : 87 veces
Agradecimiento recibido: 223 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor zx81 » 21 Jun 2022 22:20

No soy teleco y no he estudiado teoría de la señal y cosas similares, pero de ahí a asumir que se necesitan frecuencias de muestro de 88 kHz o más va un abismo. Y lo que es peor, cuando usas frecuencias de muestreo muy por encima de la frecuencia máxima tienes muchas probabilidades de aliasing, aunque parezca mentira. Un CD de música está muestreado a 44.1 kHz y suena todo (muros de sonido aparte).

Hay técnicas para, usando una frecuencia de muestreo mayor, calcular muestras de más bits por muestra que si se usara una frecuencia más baja, pero eso no aplica aquí. El PWM modula el ancho del pulso (eso es lo que significa PWM), pero no significa que la onda final tenga una frecuencia salvajemente alta que, de todas formas, no escuchan ni los perros (sinceramente, no sé el rango audible de los perros).

Para el beeper, posiblemente con 22 Khz vas que chutas, no veo a ese altavoz de juguete sacando una frecuencia de 11 kHz. Otra cosa es cuando metes en la ecuación al AY, la calidad de la emulación se ve al intentar reproducir la escala musical de la octava más alta (play "O8cdefgabC") en modo 128k, frecuencias que el beeper no puede reproducir, estoy seguro.

A falta de mayores conocimientos, mi peor dolor de cabeza fue lograr que no se perdiera nada, ni por redondeos, ni por otras razones y que todo cuadrara al sample, porque estás relacionando la frecuencia de la CPU, que hay dos porque el 48k y el 128k no van a la misma frecuencia de CPU, con la frecuencia de muestreo y eso es fatal cuando usas frecuencias típicas como 44.1 kHz que no encajas ni con cola. Si la relación frecuencias CPU/audio da un valor con infinitos decimales, también estás jodido.

Me pasé meses con la rutina del beeper en JSpeccy y la reescribí 400 veces, y aún así sigue sin satisfacerme del todo y no hace tanto encontré un motivo a ciertos ruidos indeseables que escuchaba a veces, y en no diciendo ná, te lo digo tó.
Cuando utilizo una palabra, esa palabra significa, exactamente, lo que yo quiero que signifique. Ni más, ni menos.
Humpty Dumpty

Empieza a jugar sin tener que compilar: Emulador JSpeccy
ZX Spectrum bare-metal para Raspberry PI ZXBaremulator

Avatar de Usuario
dcrespo3d
Mensajes: 137
Registrado: 04 Nov 2020 08:51
Agradecido : 121 veces
Agradecimiento recibido: 154 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor dcrespo3d » 22 Jun 2022 00:14

zx81 escribió:No soy teleco y no he estudiado teoría de la señal y cosas similares, pero de ahí a asumir que se necesitan frecuencias de muestro de 88 kHz o más va un abismo. Y lo que es peor, cuando usas frecuencias de muestreo muy por encima de la frecuencia máxima tienes muchas probabilidades de aliasing, aunque parezca mentira. Un CD de música está muestreado a 44.1 kHz y suena todo (muros de sonido aparte).

Hay técnicas para, usando una frecuencia de muestreo mayor, calcular muestras de más bits por muestra que si se usara una frecuencia más baja, pero eso no aplica aquí. El PWM modula el ancho del pulso (eso es lo que significa PWM), pero no significa que la onda final tenga una frecuencia salvajemente alta que, de todas formas, no escuchan ni los perros (sinceramente, no sé el rango audible de los perros)


Pues yo creo que sí que hacen falta frecuencias de muestreo altas, por lo menos durante una parte del proceso.

La electrónica del spectrum y el altavocillo que le puso el tito clive actúan como filtros paso bajo. Totalmente de acuerdo en que no vamos a escuchar por ahí frecuencias superiores a... 10kHz, digamos?

Pero el pin de salida de la ula está cambiando con períodos mucho más cortos, correspondientes a frecuencias mucho más altas.

Un filtro paso bajo lo que hace es ralentizar las transiciones. Supongamos (es mucho suponer, pero bueno) que el pin de la ULA pasa de 0 a 1V instantáneamente. Tras pasar por la electrónica que lo filtra y el altavoz que tendrá su respuesta en frecuencia limitada, la excursión del cono del altavoz será una curva que pasará gradualmente de un mínimo (correspondiente añl 0) y un máximo (un 1).

Algo parecido a la curva de carga y descarga de un condensador:
rc3.gif
rc3.gif (4.08 KiB) Visto 540 veces


Pero un PWM con ráfagas de periodos cortos lo que consiguen, a la salida de un filtro paso bajo (altavoz incluido), son excursiones del cono del altavoz que no abarcan todo su recorrido, sino amplitudes más pequeñas:

2022-06-21 23_38_46-Window.png
2022-06-21 23_38_46-Window.png (134.62 KiB) Visto 540 veces


En realidad la imagen la he sacado de la página de la wikipedia de la modulación delta, pero para ilustrar el concepto, el concepto me sirve. -grin

La señal rosa es la salida del pin de la ULA, y la señal azul lo que sale a la salida del filtro (con altavoz y todo). Cuando el pin de la ULA está alto, la señal sube lentamente, y cuando está bajo, la señal baja lentamente.

Lo que quiero decir es que no te puedes perder ni una sóla transición de la señal original porque entonces estarás perdiendo información.

Otra cosa es que luego hagas un filtrado / promediado y un submuestreo, pero originalmente tendrás que capturar las transiciones en su sítio, si acaso tomar muestras más grandes (mayor periodo, menor frecuencia) y asignarles un valor proporcional al área que tenía la señal en estado alto.

Volviendo a mi ejemplo anterior: a 32 tstates por muestra me salen aprox 110kHz de frecuencia de muestreo. Si promedio cada cuatro muestras...

RES:0000000110000011110001111110111111101111110001111000001100000001...
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQ


Separo en grupos de cuatro para facilitar la visión del concepto...
0000 0001 1000 0011 1100 0111 1110 1111 1110 1111 1100...
AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK

0.00 0.25 0.25 0.50 0.50 0.75 0.75 1.00 0.75 1.00 0.50


La cuarta parte de 110kHz son 27.5 kHz, y según el amigo Nyquist y su colega Shannon la máxima frecuencia representable sería la mitad, es decir, 13.75 kHz. Podría sonar parecido a un spectrum.

Vamos, a lo mejor eres capaz de programar un algoritmo que teniendo en cuenta los tiempos de las transiciones te rellene un buffer con una frecuencia de muestreo menor, de forma proporcional a las áreas que tendría la señal original, sin necesidad de calcularlo todo a una frecuencia de muestreo mayor que no oyen ni los perros. Pero conceptualmente lo que estás haciendo es un filtrado y un submuestreo.

Hace un par de años programé un emulador web bastante básico del 48k:
https://dcrespo3d.github.io/MinZX/

Tiene un lag de narices y se le pueden reprochar bastantes otras cosas, pero el sonido suena bastante decente. Relleno un buffer sobremuestreado/sobredimensionado, a partir de los tiempos de las transiciones, y luego lo promedio y submuestreo. El resultado a mí me parece muy bueno. Resuelve dignamente el sonido del Arkanoid o la demo pitstop de Tim Follin... Aunque tiene querencia por Chrome y procesadores mínimamente potentes. Carga sólo SNAs.

Vamos, que no necesitamos una frecuencia de muestreo alta en reproducción, si hacemos los cálculos bien. Pero conceptualmente SÍ que la necesitamos, otra cosa es que no calculemos directamente un buffer a esa frecuencia alta si nuestro algoritmo es suficientemente listo. :ugeek:
DavidPrograma en YouTube, GitHub

Avatar de Usuario
Eremus
Mensajes: 43
Registrado: 01 May 2022 18:10
Agradecido : 70 veces
Agradecimiento recibido: 75 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor Eremus » 22 Jun 2022 04:09

Brevemente (mañana comento vuestros posts y me explayo un poco mas que es tardecillo -grin ):

He metido la reproducción de audio en el otro core y he conseguido que suene bien reproduciendo a altas tasas de muestreo (44800hz).

Si bajo un puntito (31200hz) la cosa se sigue oyendo razonable y va mas fino aun -thumbup

Con esto respondo a la pregunta de David de si el pwm_audio se reproduce en un core aparte: se ejecuta en el que lo creas e inicias. Lo de frecuencia invalida te lo decía porque el máximo samplerate que soporta el pwm_audio son 48000hz.

Échale un ojo cuando puedas y me cuentas David: https://github.com/EremusOne/ZX-ESPectr ... otest2/src

¡Importante! Si se activa #define LOG_DEBUG_TIMING para sacar estadísticas tendremos un pequeño click de audio en cada actualización de las mismas. Es normal porque genera una microinterrupción y desaparece si se desactivan.

Y otra cosa: no es compatible con el AYSound. Hay que desactivarlo porque parece que usan los mismos recursos para generar audio. Creo que el FabGL servira como reemplazo de pwm_sound. Habra que seguir investigando pero, por ahora, algo va saliendo -grin

Buenas noches!

Avatar de Usuario
zx81
Mensajes: 469
Registrado: 23 Feb 2013 21:31
Agradecido : 87 veces
Agradecimiento recibido: 223 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor zx81 » 22 Jun 2022 12:11

dcrespo3d escribió:Vamos, a lo mejor eres capaz de programar un algoritmo que teniendo en cuenta los tiempos de las transiciones te rellene un buffer con una frecuencia de muestreo menor, de forma proporcional a las áreas que tendría la señal original, sin necesidad de calcularlo todo a una frecuencia de muestreo mayor que no oyen ni los perros. Pero conceptualmente lo que estás haciendo es un filtrado y un submuestreo.


Es que, por lo que deduzco, necesitas una frecuencia muy alta de muestreo del bit del beeper, y esa es la parte que yo me inventé (a medias), porque haciéndolo así tenía muchos problemas.

El tiempo que el bit permanece en un estado, en ciclos de reloj, son los ciclos transcurridos entre dos llamadas a out que modifican ese bit, no hace falta muestrear nada, solo restar, y con eso sabes lo que dura al t-state y sin consumir CPU apenas, ni tener que muestrear a una frecuencia muy alta para luego submuestrear.

Cuando empecé el emulador estaba muy preocupado con el tema de si Java iba a ser lo suficientemente rápido como para ejecutar todo a buen ritmo (duda vana, en aceleración máxima, en mi máquina puede llegar a 15000% de velocidad, pero yo aún no lo sabía). Así que busqué todos los métodos posibles para conseguir que fuera rápido, legales, ilegales e incluso inmorales. Gracias a esto, JSpeccy consume menos CPU que algunos emuladores escritos en C.

Me inventé una teoría que, a la postre, funciona razonablemente bien, pero que no la he leído en ninguna parte. Supongamos que un cero lo representamos con un sample == 0 y un 1 con un sample == 8000, y que la duración en t-states de un sample es de 73. Mi disparatada idea es que el sample valdrá 8000 cuando durante los 73 t-states el bit esté a 1 y, si no, tendrá un valor proporcional a los t-states en que ha estado a 1, es decir, si ha estado la mitad del tiempo a 1 y la otra mitad a cero, se asigna al sample el valor 4000. Hay que aplicar un pequeño filtro para ir suavizando la curva, pero es básicamente lo que ya hacéis, sumar a un acumulado la cuarta o la octava parte del cambio.

De modo que todo se reduce a restar, acumular al sample lo que proceda, que puede ser uno o varios, y ya, sin necesidad de muestrear el bit de beeper a frecuencias tan altas que siempre consumirá más CPU y por mucho que quieras, pierdes algo. Restando t-states el cálculo es exacto.

Hay otros métodos, como el BlipBuffer que implementó Fuse, pero lo veo inviable en un ESP32, la verdad.

En fin, espero no molestar a nadie con mis sugerencias, las pasé tan moradas con el temita que si puedo colaborar para que otros no pasen ese calvario, no me importa pegar la chapa, a riesgo de hacerme pesado. Pero si lo parezco, decidlo y dejo de incordiar. :\
Cuando utilizo una palabra, esa palabra significa, exactamente, lo que yo quiero que signifique. Ni más, ni menos.
Humpty Dumpty

Empieza a jugar sin tener que compilar: Emulador JSpeccy
ZX Spectrum bare-metal para Raspberry PI ZXBaremulator

Avatar de Usuario
Eremus
Mensajes: 43
Registrado: 01 May 2022 18:10
Agradecido : 70 veces
Agradecimiento recibido: 75 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor Eremus » 22 Jun 2022 16:15

zx81 escribió:Me pasé meses con la rutina del beeper en JSpeccy y la reescribí 400 veces, y aún así sigue sin satisfacerme del todo y no hace tanto encontré un motivo a ciertos ruidos indeseables que escuchaba a veces, y en no diciendo ná, te lo digo tó.

Oido barra! Visita al repo del Speccy por tropocientas-ava vez a cotillear -grin

dcrespo3d escribió:La electrónica del spectrum y el altavocillo que le puso el tito clive actúan como filtros paso bajo. Totalmente de acuerdo en que no vamos a escuchar por ahí frecuencias superiores a... 10kHz, digamos? Pero el pin de salida de la ula está cambiando con períodos mucho más cortos, correspondientes a frecuencias mucho más altas.

Exactamente: una cosa es la frecuencia efectiva de reproducción que no puede ser muy alta al recibirse en un altavocillo así y otra la frecuencia que produce el Spectrum y envía al altavoz.

dcrespo3d escribió:Un filtro paso bajo ...
.
... Pero conceptualmente lo que estás haciendo es un filtrado y un submuestreo.

-groupwave Muy bien explicado! De aquí salgo con un minimaster en proceso de señales -rofl

dcrespo3d escribió:Hace un par de años programé un emulador web bastante básico del 48k:
https://dcrespo3d.github.io/MinZX/ ... el sonido suena bastante decente. Relleno un buffer sobremuestreado/sobredimensionado, a partir de los tiempos de las transiciones, y luego lo promedio y submuestreo. El resultado a mí me parece muy bueno. Resuelve dignamente el sonido del Arkanoid o la demo pitstop de Tim Follin...

Pues hala, otra parada en mi peregrinación por Github -grin

zx81 escribió:Me inventé una teoría que, a la postre, funciona razonablemente bien, pero que no la he leído en ninguna parte. Supongamos que un cero lo representamos con un sample == 0 y un 1 con un sample == 8000, y que la duración en t-states de un sample es de 73. Mi disparatada idea es que el sample valdrá 8000 cuando durante los 73 t-states el bit esté a 1 y, si no, tendrá un valor proporcional a los t-states en que ha estado a 1, es decir, si ha estado la mitad del tiempo a 1 y la otra mitad a cero, se asigna al sample el valor 4000. Hay que aplicar un pequeño filtro para ir suavizando la curva, pero es básicamente lo que ya hacéis, sumar a un acumulado la cuarta o la octava parte del cambio.

Pues no tengo conocimientos suficientes para saber hasta que punto es una buena idea pero de manera intuitiva me parece un enfoque mas que razonable y de manera empírica también viendo como suena el Speccy. No creo, eso si, que sea técnicamente posible conseguir un sonido tan bueno con el ESP32 porque no podemos manejar rangos tan amplios de salida al tener un DAC de solo 8 bits.

He estado comparando calidad de audio con el Speccy sin filtrado (entiendo que la opción "Sonido de alta calidad" elimina el filtrado) en el auricular izquierdo y nuestra ultima versión en el derecho y, excepto los ocasionales pitidos de fondo de alta frecuencia que deben ser problemas de aliasing y/o de usar 8 bits, la verdad es que he quedado bastante satisfecho del resultado. -thumbup

zx81 escribió:En fin, espero no molestar a nadie con mis sugerencias, las pasé tan moradas con el temita que si puedo colaborar para que otros no pasen ese calvario, no me importa pegar la chapa, a riesgo de hacerme pesado. Pero si lo parezco, decidlo y dejo de incordiar. :\

¿Pero como puedes decir eso hombre? Si alguien incordia aquí podría ser yo que soy un recién llegado y no os llego a la suela de los zapatos en conocimientos del Spectrum y de muchas otras disciplinas. Quizá podria convertirse en un incordio que vuelvas a mencionar que puedes serlo. En ese caso te lo hare saber -grin

Voy a ver si implemento alguna de los ideas que estais comentando a ver como queda la cosa. Ya os cuento, Hasta luego!

Avatar de Usuario
Eremus
Mensajes: 43
Registrado: 01 May 2022 18:10
Agradecido : 70 veces
Agradecimiento recibido: 75 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor Eremus » 22 Jun 2022 19:09

Eremus escribió:Voy a ver si implemento alguna de los ideas que estáis comentando a ver como queda la cosa. Ya os cuento, Hasta luego!

¡Hecho! Implementada la creación del buffer en la misma función Ports:output solo si hay cambios en el bit de sonido tal y como sugirió @zx81

Resultado espectacular: donde había poco sonido la mejora es notabilísima. En la intro de Arkanoid, que machaca el puerto, tampoco está nada mal: mas de 1000 microsegundos menos -thumbup

Lo siguiente: sobremuestrear (a 32 tstates) y procesar la señal antes de submuestrearla despues a 27300hz ( muestreo a 128 tstates) para mandarla al driver PWM.

Seguimos! -grin

Avatar de Usuario
dcrespo3d
Mensajes: 137
Registrado: 04 Nov 2020 08:51
Agradecido : 121 veces
Agradecimiento recibido: 154 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor dcrespo3d » 23 Jun 2022 17:39

Eremus escribió:¡Hecho! Implementada la creación del buffer en la misma función Ports:output solo si hay cambios en el bit de sonido tal y como sugirió @zx81
Resultado espectacular: donde había poco sonido la mejora es notabilísima. En la intro de Arkanoid, que machaca el puerto, tampoco está nada mal: mas de 1000 microsegundos menos -thumbup


Por fín he podido sacar tiempo para probarlo, y el resultado es muy bueno. Empieza a sonar como debe (iba a decir "empieza a sonar muy bien" pero me pareció exagerado refiríendome al speccy -rofl )

Los pitidos del Zorro, Manic Miner, Skool Daze, etc, me suenan casi perfectos (aprecio cierto ruido casi imperceptible en la melodía monofónica del Zorro, aunque puede que sea mi mente en modo "buscar fallos").

El Arkanoid todavía suena con aliasing, pero mejora mucho respecto a pruebas anteriores. -thumbup

Eremus escribió:Lo siguiente: sobremuestrear (a 32 tstates) y procesar la señal antes de submuestrearla despues a 27300hz ( muestreo a 128 tstates) para mandarla al driver PWM.


Pues si puedes meter ese sobremuestreo-que-no-consume-como-el-sobremuestreo de @zx81, ya lo tendríamos!!!

No se si podrás hacer lo de este modo, pero si partes con el buffer a cero, y a cada muestra (que abarca 128tstates) le consigues sumar los tstates que está activa, tendríamos muestras con valores entre 0 y 128...

En cualquier caso, felicidades!!! -drinks
DavidPrograma en YouTube, GitHub

Avatar de Usuario
Eremus
Mensajes: 43
Registrado: 01 May 2022 18:10
Agradecido : 70 veces
Agradecimiento recibido: 75 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor Eremus » 27 Jun 2022 03:28

Hola de nuevo,

Después de un poco de descanso, me he echado otra sesioncita de emu y creo que ya estaría la cosa -grin

Eremus escribió:Lo siguiente: sobremuestrear (a 32 tstates) y procesar la señal antes de submuestrearla despues a 27300hz ( muestreo a 128 tstates) para mandarla al driver PWM.

Al final sobremuestreo cada 16 tstates, downsampleo sacando la media de 8 muestras y reproduzco a 27300hz. Así, para mi gusto suena muy bien y con muy poco efecto de aliasing -thumbup Puedo downsamplear mas y reproducir a 13650hz, asi el aliasing se suaviza aun mas pero no suena tan bien para mi gusto.

El rendimiento sigue siendo bueno, por encima de 50 fps, así que cuando optimicemos mas el emu la cosa solo puede ir a mejor.

Os lo dejo en el lugar habitual por si queréis probar: https://github.com/EremusOne/ZX-ESPectr ... audiotest2

Lo siguiente es ver como sacar el buffer de audio a través de la libreria FabGL para poder compatibilizarlo con el Aysound y, una vez hecho eso, me concentrare en limpiar/refactorizar el código y pasaré esta versión a mi rama master.

Así queda mi TO-DO list de ahora en adelante, por orden de prioridad:

- OSD en pantalla para mostrar, en tiempo real, estado de la carga de cinta entre otras cosas.
- Implementar emulación de bus flotante.
- Comprobar y realizar las adaptaciones necesarias para que las mejoras en multicolor, efectos de borde y audio funcionen bien en las ROMS 128K.

Sin prioridad especial pero importante:

Temporización lo mas precisa y con el menor impacto posible al rendimiento.
Mejorar la calidad de sonido del beeper.

Por lo tanto, y ahora prometo no distraerme David -grin, el siguiente objetivo es: OSD en pantalla.

Saludos ;)

Avatar de Usuario
dcrespo3d
Mensajes: 137
Registrado: 04 Nov 2020 08:51
Agradecido : 121 veces
Agradecimiento recibido: 154 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor dcrespo3d » 27 Jun 2022 20:32

Eremus escribió:Al final sobremuestreo cada 16 tstates, downsampleo sacando la media de 8 muestras y reproduzco a 27300hz. Así, para mi gusto suena muy bien y con muy poco efecto de aliasing -thumbup Puedo downsamplear mas y reproducir a 13650hz, asi el aliasing se suaviza aun mas pero no suena tan bien para mi gusto.
El rendimiento sigue siendo bueno, por encima de 50 fps, así que cuando optimicemos mas el emu la cosa solo puede ir a mejor.


Va a haber que sacar los moñecos de celebrar:

-groupwave

Lo he probado y suena muy bien, similar a como sonaba la versión con dos tareas y las esperas por instrucción en la tarea CPU. Ambas versiones tienen artefactos (y no tengo muy claro por qué), pero me parece suficientemente bueno. El caso es que distintos tipos de sonido de beeper (monofónico, polifónico, a ráfagas) suenan decentemente, no le vamos a pedir Hi-Fi al Speccy -grin

Eremus escribió:Lo siguiente es ver como sacar el buffer de audio a través de la libreria FabGL para poder compatibilizarlo con el Aysound y, una vez hecho eso, me concentrare en limpiar/refactorizar el código y pasaré esta versión a mi rama master.
Saludos ;)


Tienes mi versión recortada de FabGL, que sólo usa la parte de la librería que hace falta para el AySound. Ojalá se pueda compatibilizar con el pwm_audio -yes2
DavidPrograma en YouTube, GitHub

Avatar de Usuario
Eremus
Mensajes: 43
Registrado: 01 May 2022 18:10
Agradecido : 70 veces
Agradecimiento recibido: 75 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor Eremus » 03 Jul 2022 21:49

Hola!

Tras un pequeño impás derivado de lo que viene a ser LA-PUTA-BIDA(tm) -grin ya me pude poner con el emu y rematar el tema del audio.

dcrespo3d escribió:Tienes mi versión recortada de FabGL, que sólo usa la parte de la librería que hace falta para el AySound. Ojalá se pueda compatibilizar con el pwm_audio -yes2


Al final, como bien sabes ya, encontré la manera de redirigir tu emulación del chip AY a través de la librería pwm_audio y tras unos ajustitos aquí y allá para que todo sonara lo "mas mejor" posible, ya esta el emu actualizado en el repo.

He probado todas las cosas que se me han ocurrido para sacar el sonido mas limpio posible y, tras todas ellas, creo que puedo afirmar que con el DAC del ESP32 no se puede conseguir mucho mas de lo que tenemos. Probe a volcar diez segundos de buffer de audio a un fichero y reproducirlo en Audacity y sonaba limpio de narices, así que la "suciedad" que podáis percibir en el audio la achaco a las limitaciones del hardware. Poco mas creo que se puede hacer sin soluciones externas (filtros, tarjetas I2S con DACS de mas calidad, etc...)

Así que, resumiendo, ya tenemos una versión del emu con carga de tap operativa y "tape traps" semifuncionales, los modos multicolor perfectamente operativos y el sonido del beeper y del chip AY mejorado (con control de volumen mediante F9 y F10). También tiene soporte experimental de los efectos de borde aunque por la gracia de verlos funcionar mas que otra cosa pq ralentizan demasiado el emu.

Disponible, como siempre en: https://github.com/EremusOne/ZX-ESPectr ... e/monohilo y, en breve si David lo tiene a bien, en su repo tambien: https://github.com/dcrespo3d/ZX-ESPectrum-Wiimote

Saludos ;)

spectrum3
Mensajes: 22
Registrado: 12 Feb 2021 22:58
Agradecido : 14 veces
Agradecimiento recibido: 14 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor spectrum3 » 04 Jul 2022 12:46

Y ya suena bien los juegos con chip ay?. Que era una de las cosillas que faltaban por pulir. Gracias.

ackerman
Mensajes: 315
Registrado: 05 Feb 2019 21:32
Ubicación: Asturias
Agradecido : 131 veces
Agradecimiento recibido: 257 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor ackerman » 04 Jul 2022 19:23

Eremus escribió:He probado todas las cosas que se me han ocurrido para sacar el sonido mas limpio posible y, tras todas ellas, creo que puedo afirmar que con el DAC del ESP32 no se puede conseguir mucho mas de lo que tenemos. Probe a volcar diez segundos de buffer de audio a un fichero y reproducirlo en Audacity y sonaba limpio de narices, así que la "suciedad" que podáis percibir en el audio la achaco a las limitaciones del hardware. Poco mas creo que se puede hacer sin soluciones externas (filtros, tarjetas I2S con DACS de mas calidad, etc...)


Enhorabuena. -drinks -drinks
Está claro que no soy la persona más indicada para las pruebas de audio, porque yo sólo presto atención a que el proceso de audio consuma poca CPU y se pueda migrar lo más rápido posible a otras plataformas.

He probado rápido, y a mi me gusta el resultado.
Respecto a la suciedad, supongo que te refieres al chascarrido, estilo al ruido en las radios cuando pasaba un ciclomotor cerca, por las bujias. Lo he notado en el test de speaker de la ROM de diagnósticos, respecto a la salida digital clásica. También algún sonido estilo juguete escacharrado cuando se quedaba sin pilas. Pero en cuanto uno está jugando, se olvida de todo. Son cosas que se notan si se tiene auriculares o se está pegado intentando encontrar el mínimo detalle. No lo considero un fallo ni nada por estilo. -drinks

Una cosa, que no es por que sea bug, ni nada, que he notado, es al irme a la ROM de diagnósticos, en el test de AY de 128K, que no reproduce ningún canal, ni el noise. No lo digo por nada, sólo porque era donde siempre probaba cuando no quería testear el AY de un juego, y siempre me tiraba. Que igual en realidad, no tiene que sonar nada.

Eremus escribió:También tiene soporte experimental de los efectos de borde aunque por la gracia de verlos funcionar mas que otra cosa pq ralentizan demasiado el emu


No te preocupes mucho, ya lo tienes. Si al ESP32 se le quita el proceso de VGA con DMA, y se usa un display con SPI, ya aparece el exceso de CPU, que falta. Por eso muchos desarrolladores, prefieren LCD o se van al Teensy para los emulatas.

Eremus escribió:He probado todas las cosas que se me han ocurrido para sacar el sonido mas limpio posible y, tras todas ellas, creo que puedo afirmar que con el DAC del ESP32 no se puede conseguir mucho mas de lo que tenemos.

Es que el ESP32 no tiene DAC, sino un pwm de 1 bit. Espressif lo metió ahi, a calzador, se centró en el pwm por hardware, y dijo, mira un DAC, en plan "si cuela, cuela, y sino, me la ...". Comparar eso con un R2R o un DAC de 4 u 8 bits, es hacerse daño. Está todo en las gráficas que habéis comentado, pero sin falta de fórmulas, hay 2 ejemplos claros donde el pwm fracasa respecto a un DAC:
  • Usar un speaker piezo eléctrico, que no sonará nada.
  • Hacer de audio modem en radioafición en la etapa de micrófono, que entre la pre Emphasis y de Emphasis de entrada, así como armónicos, te quedas con un mojón.
La placa TTGO tiene un amplificador de audio, el NS4150 de 3W, que ya tiene filtro. Por tanto, habrá diferencias entre la salida directa y la del amplificador, así como el aparato final a la hora de usar pwm.

Avatar de Usuario
dcrespo3d
Mensajes: 137
Registrado: 04 Nov 2020 08:51
Agradecido : 121 veces
Agradecimiento recibido: 154 veces

Re: Estreno nuevo subforo y avances emulador Spectrum dcrespo

Mensajepor dcrespo3d » 04 Jul 2022 20:56

Eremus escribió:Disponible, como siempre en: https://github.com/EremusOne/ZX-ESPectr ... e/monohilo y, en breve si David lo tiene a bien, en su repo tambien: https://github.com/dcrespo3d/ZX-ESPectrum-Wiimote


Hola, he mergeado tu rama monohilo en mi rama master. A partir de ahora, el monohilo es el desarrollo principal. He dejado en la antigua rama lilygo-ttgo-vga32 la versión antigua con dos tareas.

Al final estaba mal lo del clamp que propuse y guarreaba el sonido... lo que no entiendo es porqué el día que te propuse el trozo de código lo probé y sonaba bien...

El caso que es que el arkanoid sonaba otra vez mal. Para hacer el clamp bien, hay que hacerlo centrado en cero: pasar todo a rango signed (-128 a 127) antes de sumar, sumar beeper + AY, clampear a [-128, 127] y tras la suma y el clampeo volver a pasarlo todo a rango unsigned (0 a 255).

Con esta correccion ya vuelve a sonar el beeper bien, y tenemos multicolor, y TAP. -thumbup

Ya está disponible en https://github.com/dcrespo3d/ZX-ESPectrum-Wiimote
DavidPrograma en YouTube, GitHub


Volver a “Desarrollo emuladores ESP32”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado