TU ANUNCIO / YOUR PUBLICITY

AQUÍ PODRÍA ESTAR TU ANUNCIO: / HERE COULD BE YOUR AD E-mail
Mostrando entradas con la etiqueta sounds fly. Mostrar todas las entradas
Mostrando entradas con la etiqueta sounds fly. Mostrar todas las entradas

domingo, 2 de noviembre de 2014

The flight of the fly, second part/ El vuelo de la mosca, segunda parte

Vamos a hacer el paso inverso. Partimos de una canción y la pasamos a wav. Esto lo hacemos con cualquier convertidor de sonido a wav. La razón de utilizar un archivo wav es la facilidad de abrir tal tipo de archivo sin compresión.

Let's do the reverse step. We start with a song and pass it to wav. We do this with any audio to wav converter. The reason for using a wav file is the ease of opening such files without compression.

Utilizaremos Visual Basic 6. Lo primero son las definiciones:

We will use Visual Basic 6. The first are the definitions:

Private Const SND_ALIAS = &H10000
Private Const SND_ALIAS_ID = &H110000
Private Const SND_ALIAS_START = 0
Private Const SND_APPLICATION = &H80
Private Const SND_ASYNC = &H1
Private Const SND_FILENAME = &H20000
Private Const SND_LOOP = &H8
Private Const SND_MEMORY = &H4
Private Const SND_NODEFAULT = &H2
Private Const SND_NOSTOP = &H10
Private Const SND_NOWAIT = &H2000
Private Const SND_PURGE = &H40
Private Const SND_RESERVED = &HFF000000
Private Const SND_RESOURCE = &H40004
Private Const SND_SYNC = &H0
Private Const SND_TYPE_MASK = &H170007
Private Const SND_VALID = &H1F
Private Const SND_VALIDFLAGS = &H17201F

Private Declare Function PlaySoundFile Lib "winmm.dll" Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
Private Declare Function PlaySoundMemory Lib "winmm.dll" Alias "PlaySoundA" (ptrMemory As Any, ByVal hModule As Long, ByVal dwFlags As Long) As Long
Private Declare Function playSound Lib "winmm.dll" Alias "PlaySoundA" (ByVal sndToPlay As String, ByVal handleModule As Long, ByVal PS_Flags As Long) As Long

Type WaveHeader
  riff As String * 4
  riffdatasize As Long 
  wave As String * 4
End Type
  
Type WaveFormat
  fmt As String * 4 
  formatsize As Long
  formatTag As Integer 
  nChannels As Integer ' for mono the value is 1.
  samplesPerSecond As Long ' 44100 means cd quality sound
  aveBytesPerSecond As Long 
  blockAlign As Integer 
  bitsPerSample As Integer
End Type

Private Type WaveDatachunk
  dataposition As String * 4 
  wavedatasize As Long 
End Type
  
  Dim wh As WaveHeader
  Dim wf As WaveFormat
  Dim dc As WaveDatachunk
  
  Dim filename As String
  Const MusicMultiplicationFactor As Double = 2 ^ (1 / 12) 
  Const PI As Double = 3.14159265358979
  Dim Esc As Single
  Dim BaseFrequency As Single
 Dim Frequency As Single  Dim Amplitude As Single
  Dim DataValue() As Integer

Lo segundo es la lectura del archivo wav:
The second is reading the wav-file:

Sub Lectura_y_Dibujo()
 Esc = Val(Text1) 'Multiplicador para ajustarnos a la escala

  'iniciamos el objeto Picture1
 Picture3.Cls: Picture1.ScaleWidth=2000: Picture1.ScaleHeight=2000: Picture1.DrawWith=2

  'Diálogo para abrir un fichero
 cd1.Filter = "Sonidos (*.wav)|*.wav"
 cd1.ShowOpen: fichero = cd1.filename
 Open fichero For Binary As #1
    Get #1, , wh
    Get #1, , wf
    Get #1, , dc
  'Abrimos un cacho del fichero
    dc.wavedatasize = 1000000
    ReDim DataValue(dc.wavedatasize)
    uu = 0: cal = QBColor(14)
    For i = 1 To dc.wavedatasize / 2 / 2
      j = (i - 1) * 2
      Get #1, , DataValue(j)
      x = Esc * DataValue(j) / 32.768 + 500
  'Picture4 es un objeto con el dibujo del arco iris de 17985 puntos de ancho    
      colo = Picture4.Point((i Mod 1000) / 1000 * 17985, 1)
      Get #1, , DataValue(j + 1)
      y = Esc * DataValue(j + 1) / 32.768 + 500
      Picture1.Line (X1, Y1)-(x, y), colo
      t = i Mod 1000: t2 = t / 2 + 1000: t1 = (t - 1) / 2 + 1000
      Picture1.DrawWidth = 2
      Picture1.Line (t1, Y1)-(t2, y), colo
      Picture1.Line (X1, t1)-(x, t2), colo
      Picture1.Line (X1, Y1)-(x, y), colo
      X1 = x: Y1 = y
       If i Mod 2 = 0 Then
         If t = 0 Then Picture1.Cls: X1 = 500: Y1 = 500
         Lineaf x, y, t2, y, cal
         Lineaf x, y, x, t2, cal
         DoEvents
        'If i Mod 2 = 0 Then SavePicture Picture1.Image, "D:\dibus\" & Format(uu, "000000") & ".bmp": uu = uu + 1
         Lineaf x, y, t2, y, cal
         Lineaf x, y, x, t2, cal
         If i Mod 10000 = 0 Then Picture1.Cls: Picture1.PSet (500, 500): '  Stop
    End If
      Next i
Close #1
End Sub

Sub Lineaf(ByVal n As Integer, ByVal m As Integer, ByVal p As   'Para hacer que aparezca y desaparezca las líneas de seguimiento
Integer, ByVal q As Integer, ByVal cu As Long)
Picture1.DrawMode = 7:Picture1.DrawWidth = 2
Picture1.Line (n, m)-(p, q), cu
Picture1.DrawWidth = 1:Picture1.DrawMode = 13
End Sub

Un ejemplo / An example:


Para una balada de XXXXX (no digo ni el autor ni la canción para no tener problemas de derechos de autor. Sólo digo que se trata de una balada Heavy:

This is graph obtained from transcribing 1 second a heavy ballad:

















sábado, 1 de noviembre de 2014

The flight of the fly / El vuelo de la mosca

Un día, en la facultad, en una tediosa clase, aburrido, me fijé en una mosca que tras posarse en la mesa de delante, se movía haciendo círculos inacabados. Pareciera que éstos los repitiera una y otra vez. Intenté garabatear su movimiento y me salían figuras curvas que se cerraban finalmente. La clase trataba de movimiento vibratorios y se me ocurrió proyectar el movimiento en uno de los ejes y añadir el tiempo en el eje de abscisas. Curiosamente se parecía a lo que el profesor trataba de explicar con el concepto de armónicos.

Como una imagen vale más de mil palabras ( y un vídeo, por tanto, más de un millón) os muestro algo parecido, en bonito, de lo que dibujara:

One day; in the faculty, a tedious class. I was bored. I noticed a fly after landing at the front desk, moved by unfinished circles. They seem to repeat them again and again. I tried to scribble their movement: The teacher theme was vibratory motion. I happened to project the movement in one axis and add time in the horizontal axis. Interestingly resembled what the teacher was trying to explain the concept of harmonics. 

As a picture is worth a thousand words (and a video, therefore, more than a million) I show you something, in nice, what drew:


¿Cómo está hecho el dibujo? / How is made the design?


Lo primero es colocar unos cuantos puntos:
The first is to put a few points:


Lo segundo es unir los punos 1-2, 2-3 y 3-1 con una semirrecta de origen en el primer punto:
The second is to connect the points 1-2, 2-3 and 3-1 with a halft-straight. The origin of this will be the first point

El tercer paso es situar un punto azar y hacerlo girar en torno al punto 1 hasta que choque con la semirrecta 1-2. En ese momento girará en torno al punto 2 hasta que choque con la recta 2-3. Y así sucesivamente:

The third step is to place a random point and rotate around the point 1 until collision with the line 1-2. Then it will rotate around point 2 until it hits the line 2-3. And so on:

Gif animado del vuelo de la mosca con varios pasos intermedios

¿Qué mas se puede hacer con la onda creada?
Con la escala de tiempo adecuada hemos creado sonidos. La forma de guardar un sonido es la siguiente:
Se crea un Tipo para la lectura / guarda de datos:

What else can you do with the wave created? 
With the appropriate time scale we created sounds. How to save a sound is: 
One type is created to read / save data:

Type WaveHeader 
  riff As String * 4
  riffdatasize As Long      
  wave As String * 4 '
End Type
  
Type WaveFormat 
  fmt As String * 4 
  formatsize As Long 
  formatTag As Integer 
  nChannels As Integer 
  samplesPerSecond As Long 
  aveBytesPerSecond As Long 
  blockAlign As Integer 
  bitsPerSample As Integer
End Type

Type WaveDatachunk 
  dataposition As String * 4 
  wavedatasize As Long 
End Type

Se le dan los siguientes valores:

wh.riff = "RIFF" 
wh.wave = "WAVE" 
wh.riffdatasize = CInt(0)

wf.fmt = "fmt " 
wf.formatsize = 16 
wf.formatTag = 1 
wf.nChannels = 2 ' stereo, 1 para Mono
wf.samplesPerSecond = 96000 ' 44100 para calidad CD
wf.aveBytesPerSecond = wf.nChannels * wf.samplesPerSecond * 2
wf.bitsPerSample = 16 '  integer type
wf.blockAlign = (wf.bitsPerSample * wf.nChannels) / 8 

dc.dataposition = "data"  
dc.wavedatasize = CInt(0)

Para guardar los datos:

[...]
Open fichero For Binary As #1
    Put #1, , wh
    Put #1, , wf
    Put #1, , dc

    For i = 1 To finfin
      Put #1, , DataValue(i)
    Next i

fileSize = LOF(1)               
Put #1, 5, CLng(fileSize - 8)
Put #1, 41, CLng(fileSize - 44)
Close #1
[...]

Los sonidos de varias de las pruebas están disponibles aquí:
The sounds of several tests are available  here:

Lógicamente también se nos ha ocurrido que podríamos hacer un programa que leyera estos datos y así poder hacer el vuelo de la mosca a posteriori.

Of course we also have happened that could make a program to read this data and be able to make the flight fly afterwards.