Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 31-05-2008
Avatar de Guillermo80
Guillermo80 Guillermo80 is offline
Miembro
 
Registrado: may 2007
Posts: 87
Poder: 17
Guillermo80 Va por buen camino
Datos interpaginados a array

Hola, tengo una aplicación que me funciona bien, pero teóricamente no entiendo del todo cómo lo hace, me explico: se trata de alimentar un codificador de audio, al cual le llega un array tipo byte con las muestras interpaginadas de los canales L y R. Para ello primero voy leyendo el wav de entrada, que voy guardando a cada pasada del bucle, con Blockread, guardo en un array bufer de 2*n posiciones. Después con otro bucle interno al primero se van interpaginando las muestras guardándose en otro array pcm de mitad de tamaño, o sea, n. Cuando termina este subbucle, coge y alimenta al codificador. Para que se entienda, voy a poner el trozo de código que interesa:

Cita:
...dentro de un while, ya llego aqui con las muestras leídas del wav al array buffer...

for i:=0 to (necesarias*channels-1) do
begin

pcm[i] := buffer[2*i+1] shl 8 or buffer[2*i];
end;
//se alimenta el codificador
ok := FLAC__stream_encoder_process_interleaved(pencoder, pcm, necesarias);

...sigue dentro del while más operaciones y luego vuelta a empezar...
Dentro del for va guardando en pcm las posiciones impares según entiendo, pero lo que no entiendo es el porqué del desplazamiento shl, y la función del or, no entiendo en qué caso cogería buffer[2*i]

No pongo más segmentos de código porque no interesa saber nada más que lo que aquí muestro. La clave está en por qué utilizo un bufer de mitad de tamaño para interpaginar las muestras, cómo se interpaginan dentro del for, o sea, cuándo se cogen las pares.
Responder Con Cita
  #2  
Antiguo 31-05-2008
Avatar de ixMike
ixMike ixMike is offline
Miembro
 
Registrado: feb 2004
Posts: 1.151
Poder: 22
ixMike Va por buen camino
¿Es mi impresión, o el array llamado PCM va a ser el contenido del audio en mono? No sé, igual estoy algo confundido, pero eso de que opere con buffer[2*i+1] y buffer[2*i] da toda la impresión de que se estén mezclando ambos canales, en ese caso la operación adecuada para sumar ambos canales sea esa con shl y or.

Salu2, y perdón si sólo estoy confundido y no te he ayudado .
Responder Con Cita
  #3  
Antiguo 31-05-2008
Avatar de Guillermo80
Guillermo80 Guillermo80 is offline
Miembro
 
Registrado: may 2007
Posts: 87
Poder: 17
Guillermo80 Va por buen camino
Hola ixMike, gracias por tu interés, estás cerca de dar con la clave, mira te explico un poco mejor ahora que he estado repasando un poco:

buffer recordemos que es un array de bytes, o sea, cada posición, un byte.
EL flujo de datos wav que se va a almacenar en buffer va así, sabiendo que una muestra de un canal ocupa 2bytes:

Cita:
2bytes canal L, 2bytes canal R, 2bytes canal L, 2bytes canal R, ....
Por lo tanto en buffer quedará así almacenado:

Cita:
1byte L, 1byte L, 1byte R, 1byte R, 1byte L, 1byte L, 1byte R, 1byte R, ...
Ostras, a medida que escribo creo que lo voy entendiendo yo también, ahora viene la instrucción que va dentro del bucle for, que a mi entender, es de mitad de tamaño porque agrupa en una posición las muestras de buffer i e i+1 de un canal en una posición de pcm, y esto lo hace gracias al desplazamiento de 8 bits (1byte) a la izquierda de la muestra i, que concatena a su derecha la muestra i+1:


Cita:
pcm[i] := buffer[2*i+1] shl 8 or buffer[2*i];
Ahora, creo que eso es así, pero no entiendo cómo funciona el operador or en esta situación de trabajar bit a bit, ¿podrías explicármelo para terminar de entender cómo en una misma instrucción hace lo que he explicado?
Responder Con Cita
  #4  
Antiguo 31-05-2008
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Hola!

Cita:
Empezado por Guillermo80 Ver Mensaje
...no entiendo cómo funciona el operador or en esta situación de trabajar bit a bit...
Suponiendo que tienes un byte B1 con un valor decimal de 20 (en binario, 00010100) y segundo byte B2 con un valor decimal de 12 (en binario, 00001100), la expresión
Código Delphi [-]
B1 Or B2
te devolverá un entero de valor decimal 28 (en binario, 00011100).

00010100 (20)
Or
00001100 (12)
------------------
00011100 (28) <-- (se integró el bit de valor 8 al los bits de 20)

Or toma todos los bits activos (los que están en 1) de ambos operandos.

And toma todos los bits que estén activos en ambos operandos.

XOr toma todos los bits que estén activos en alguno de los operandos pero inactivos en el otro.

Espero te sirva de algo esta modesta explicación.

Un saludo Or abrazo.

Al González.
Responder Con Cita
  #5  
Antiguo 31-05-2008
Avatar de Guillermo80
Guillermo80 Guillermo80 is offline
Miembro
 
Registrado: may 2007
Posts: 87
Poder: 17
Guillermo80 Va por buen camino
Perfecto

Hola Al, sólo tengo que decirte que tu explicación encaja como un guante, ahora entiendo cómo trabaja el bloque completo. Hacía tiempo que no usaba or para sumar bits, estaba obcecado pensando en "el otro or", o sea, o cojo la expresión evaluada a la izquierda o la de la derecha (es que hoy estoy espeso).

Bueno, pues dejo la explicación final y resumidaara una muestra de un canal tenemos 2bytes, al más significativo lo corro 8 bits a la izquierda con shl 8, y a continuación se le suma con el operador or el byte menos significatico, cuyo resultado va a una posición del array pcm. Para una muestra completa de una posición de pcm resultaría del siguiente ejemplo:

byte1 + byte2 = muestra completa canal L
byte1 = 11000001; byte2 = 01010001
Tomando que el byte1 debe ser el más significativo, debe ser el que desplacemos 8 bits a la izquierda:

muestra1 equivalente = 1100000100000000 (habrá que guardarlo en un entero)

Ahora hago la suma de ambas muestras (guardadas en variables tipo entero):

1100000100000000
0000000001010001 +
--------------------
1100000101010001 --> será una muestra del array pcm, de tipo entero

¡ Todo encaja ! Gracias a los dos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
pasar un tipo de datos (array of record) entre aplicaciones mauqu Varios 4 26-10-2007 20:04:31
BMP en un array lacatella Gráficos 2 27-07-2006 20:36:27
Meter un Array de strings con Datos en un PSafearray camomilass OOP 1 28-06-2006 12:09:39
Como Asignar Variable Tipo Array de Tform a otro Array del Mismo tipo morfeo21 Varios 5 17-08-2004 17:39:51
Como guardar una array en una base datos? ciscu Varios 3 11-02-2004 09:27:49


La franja horaria es GMT +2. Ahora son las 17:58:22.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi