Commit 1af1e3b1 authored by Kai Lauterbach's avatar Kai Lauterbach Committed by André Weber

atmo: add support for new device fnordlicht

Fnordlicht - is a serial device with up to four channels
- http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
- http://github.com/fd0/fnordlicht/Signed-off-by: default avatarAndré Weber <atmo@videolan.org>
parent ac3514ed
......@@ -71,6 +71,7 @@ SOURCES_atmo = atmo/atmo.cpp \
atmo/DmxTools.cpp atmo/DmxTools.h \
atmo/AtmoMultiConnection.cpp atmo/AtmoMultiConnection.h \
atmo/MoMoConnection.cpp atmo/MoMoConnection.h \
atmo/FnordlichtConnection.cpp atmo/FnordlichtConnection.h \
atmo/AtmoPacketQueue.cpp atmo/AtmoPacketQueue.h
SOURCES_gradfun = gradfun.c gradfun.h
noinst_HEADERS = filter_picture.h
......
......@@ -44,6 +44,10 @@ CAtmoConfig::CAtmoConfig()
m_AtmoZoneDefCount = -1;
m_DMX_BaseChannels = NULL;
m_chWhiteAdj_Red = NULL;
m_chWhiteAdj_Green = NULL;
m_chWhiteAdj_Blue = NULL;
LoadDefaults();
}
......@@ -59,6 +63,10 @@ CAtmoConfig::~CAtmoConfig() {
m_ZoneDefinitions = NULL;
}
delete []m_chWhiteAdj_Red;
delete []m_chWhiteAdj_Green;
delete []m_chWhiteAdj_Blue;
free( m_DMX_BaseChannels );
#if defined (_ATMO_VLC_PLUGIN_)
......@@ -99,8 +107,6 @@ void CAtmoConfig::LoadDefaults() {
m_UpdateEdgeWeightningFlag = 0;
m_Software_gamma_mode = agcNone;
m_Software_gamma_red = 10;
m_Software_gamma_green = 10;
......@@ -112,6 +118,17 @@ void CAtmoConfig::LoadDefaults() {
m_WhiteAdjustment_Blue = 255;
m_UseSoftwareWhiteAdj = 1;
m_WhiteAdjPerChannel = ATMO_FALSE;
m_chWhiteAdj_Count = 0;
delete []m_chWhiteAdj_Red;
delete []m_chWhiteAdj_Green;
delete []m_chWhiteAdj_Blue;
m_chWhiteAdj_Red = NULL;
m_chWhiteAdj_Green = NULL;
m_chWhiteAdj_Blue = NULL;
m_ColorChanger_iSteps = 50;
m_ColorChanger_iDelay = 25;
......@@ -145,6 +162,7 @@ void CAtmoConfig::LoadDefaults() {
m_LiveView_DisplayNr = 0;
m_LiveView_FrameDelay = 30;
m_LiveView_GDI_FrameRate = 25;
m_LiveView_RowsPerFrame = 0;
m_Hardware_global_gamma = 128;
......@@ -161,6 +179,7 @@ void CAtmoConfig::LoadDefaults() {
m_DMX_RGB_Channels = 5; // so wie atmolight
m_MoMo_Channels = 3; // default momo, there exists also a 4 ch version!
m_Fnordlicht_Amount = 2; // default fnordlicht, there are 2 fnordlicht's!
m_ZonesTopCount = 1;
m_ZonesBottomCount = 1;
......@@ -168,7 +187,6 @@ void CAtmoConfig::LoadDefaults() {
m_ZoneSummary = ATMO_FALSE;
UpdateZoneCount();
clearAllChannelMappings();
m_CurrentChannelAssignment = 0;
CAtmoChannelAssignment *temp = new CAtmoChannelAssignment();
......@@ -201,6 +219,25 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
this->m_WhiteAdjustment_Blue = pAtmoConfigSrc->m_WhiteAdjustment_Blue;
this->m_UseSoftwareWhiteAdj = pAtmoConfigSrc->m_UseSoftwareWhiteAdj;
this->m_WhiteAdjPerChannel = pAtmoConfigSrc->m_WhiteAdjPerChannel;
this->m_chWhiteAdj_Count = pAtmoConfigSrc->m_chWhiteAdj_Count;
delete []m_chWhiteAdj_Red;
delete []m_chWhiteAdj_Green;
delete []m_chWhiteAdj_Blue;
if(m_chWhiteAdj_Count > 0)
{
m_chWhiteAdj_Red = new int[ m_chWhiteAdj_Count ];
m_chWhiteAdj_Green = new int[ m_chWhiteAdj_Count ];
m_chWhiteAdj_Blue = new int[ m_chWhiteAdj_Count ];
memcpy(m_chWhiteAdj_Red, pAtmoConfigSrc->m_chWhiteAdj_Red, sizeof(int) * m_chWhiteAdj_Count);
memcpy(m_chWhiteAdj_Green, pAtmoConfigSrc->m_chWhiteAdj_Green, sizeof(int) * m_chWhiteAdj_Count);
memcpy(m_chWhiteAdj_Blue, pAtmoConfigSrc->m_chWhiteAdj_Blue, sizeof(int) * m_chWhiteAdj_Count);
} else {
m_chWhiteAdj_Red = NULL;
m_chWhiteAdj_Green = NULL;
m_chWhiteAdj_Blue = NULL;
}
this->m_IsSetShutdownColor = pAtmoConfigSrc->m_IsSetShutdownColor;
this->m_ShutdownColor_Red = pAtmoConfigSrc->m_ShutdownColor_Red;
this->m_ShutdownColor_Green = pAtmoConfigSrc->m_ShutdownColor_Green;
......@@ -223,7 +260,6 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
this->m_show_statistics = pAtmoConfigSrc->m_show_statistics;
this->m_LiveView_EdgeWeighting = pAtmoConfigSrc->m_LiveView_EdgeWeighting;
this->m_LiveView_BrightCorrect = pAtmoConfigSrc->m_LiveView_BrightCorrect;
this->m_LiveView_DarknessLimit = pAtmoConfigSrc->m_LiveView_DarknessLimit;
......@@ -236,6 +272,7 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
this->m_LiveView_DisplayNr = pAtmoConfigSrc->m_LiveView_DisplayNr;
this->m_LiveView_FrameDelay = pAtmoConfigSrc->m_LiveView_FrameDelay;
this->m_LiveView_GDI_FrameRate = pAtmoConfigSrc->m_LiveView_GDI_FrameRate;
this->m_LiveView_RowsPerFrame = pAtmoConfigSrc->m_LiveView_RowsPerFrame;
this->m_ZonesTopCount = pAtmoConfigSrc->m_ZonesTopCount;
this->m_ZonesBottomCount = pAtmoConfigSrc->m_ZonesBottomCount;
......@@ -255,6 +292,8 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
this->m_MoMo_Channels = pAtmoConfigSrc->m_MoMo_Channels;
this->m_Fnordlicht_Amount = pAtmoConfigSrc->m_Fnordlicht_Amount;
this->m_CurrentChannelAssignment = pAtmoConfigSrc->m_CurrentChannelAssignment;
clearChannelMappings();
......@@ -278,8 +317,6 @@ void CAtmoConfig::Assign(CAtmoConfig *pAtmoConfigSrc) {
UpdateZoneDefinitionCount();
}
int CAtmoConfig::getNumChannelAssignments() {
int z=0;
for(int i=0;i<10;i++)
......@@ -336,8 +373,6 @@ void CAtmoConfig::UpdateZoneCount()
m_computed_zones_count++;
}
int CAtmoConfig::getZoneCount()
{
return(m_computed_zones_count);
......@@ -423,3 +458,50 @@ void CAtmoConfig::setDMX_BaseChannels(char *channels)
m_DMX_BaseChannels = strdup(channels);
}
void CAtmoConfig::getChannelWhiteAdj(int channel,int &red,int &green,int &blue)
{
if(channel >= m_chWhiteAdj_Count)
{
red = 256;
green = 256;
blue = 256;
} else {
red = m_chWhiteAdj_Red[ channel ];
green = m_chWhiteAdj_Green[ channel ];
blue = m_chWhiteAdj_Blue[ channel ];
}
}
void CAtmoConfig::setChannelWhiteAdj(int channel,int red,int green,int blue)
{
if(channel >= m_chWhiteAdj_Count)
{
int *tmp = new int[channel+1];
if(m_chWhiteAdj_Red)
memcpy( tmp, m_chWhiteAdj_Red, m_chWhiteAdj_Count * sizeof(int) );
delete []m_chWhiteAdj_Red;
m_chWhiteAdj_Red = tmp;
tmp = new int[channel + 1];
if(m_chWhiteAdj_Green)
memcpy( tmp, m_chWhiteAdj_Green, m_chWhiteAdj_Count * sizeof(int) );
delete []m_chWhiteAdj_Green;
m_chWhiteAdj_Green = tmp;
tmp = new int[channel + 1];
if(m_chWhiteAdj_Blue)
memcpy( tmp, m_chWhiteAdj_Blue, m_chWhiteAdj_Count * sizeof(int) );
delete []m_chWhiteAdj_Blue;
m_chWhiteAdj_Blue = tmp;
m_chWhiteAdj_Count = channel + 1;
}
m_chWhiteAdj_Red[channel] = red;
m_chWhiteAdj_Green[channel] = green;
m_chWhiteAdj_Blue[channel] = blue;
}
......@@ -19,11 +19,10 @@
# include <string.h>
#endif
class CAtmoConfig {
protected:
int m_IsShowConfigDialog;
int m_IsShowConfigDialog;
#if defined(_ATMO_VLC_PLUGIN_)
char *m_devicename;
char *m_devicenames[3]; // additional Devices ?
......@@ -42,6 +41,12 @@ class CAtmoConfig {
int m_WhiteAdjustment_Green;
int m_WhiteAdjustment_Blue;
ATMO_BOOL m_WhiteAdjPerChannel;
int m_chWhiteAdj_Count;
int *m_chWhiteAdj_Red;
int *m_chWhiteAdj_Green;
int *m_chWhiteAdj_Blue;
protected:
int m_IsSetShutdownColor;
int m_ShutdownColor_Red;
......@@ -76,7 +81,6 @@ class CAtmoConfig {
CAtmoZoneDefinition **m_ZoneDefinitions;
int m_AtmoZoneDefCount;
/*
zone layout description for generating the default Zone weightning
*/
......@@ -94,7 +98,6 @@ class CAtmoConfig {
public:
int getZoneCount();
protected:
/* Live View Parameters (most interesting) */
AtmoFilterMode m_LiveViewFilterMode;
......@@ -104,6 +107,9 @@ class CAtmoConfig {
ATMO_BOOL m_show_statistics;
// number of rows to process each frame
int m_LiveView_RowsPerFrame;
// weighting of distance to edge
int m_LiveView_EdgeWeighting; // = 8;
// brightness correction
......@@ -154,6 +160,9 @@ class CAtmoConfig {
protected:
int m_MoMo_Channels;
protected:
int m_Fnordlicht_Amount;
protected:
AtmoGammaCorrect m_Software_gamma_mode;
......@@ -165,7 +174,6 @@ class CAtmoConfig {
public:
volatile int m_UpdateEdgeWeightningFlag;
public:
CAtmoConfig();
virtual ~CAtmoConfig();
......@@ -210,6 +218,13 @@ class CAtmoConfig {
ATMO_BOOL isUseSoftwareWhiteAdj() { return m_UseSoftwareWhiteAdj; }
void setUseSoftwareWhiteAdj(ATMO_BOOL value) { m_UseSoftwareWhiteAdj = value; }
/* White ADJ per Channel settings */
ATMO_BOOL isWhiteAdjPerChannel() { return m_WhiteAdjPerChannel; }
void setWhiteAdjPerChannel( ATMO_BOOL value) { m_WhiteAdjPerChannel = value; }
void setChannelWhiteAdj(int channel,int red,int green,int blue);
void getChannelWhiteAdj(int channel,int &red,int &green,int &blue);
int isSetShutdownColor() { return m_IsSetShutdownColor; }
void SetSetShutdownColor(int value) { m_IsSetShutdownColor = value; }
int getShutdownColor_Red() { return m_ShutdownColor_Red; }
......@@ -236,7 +251,6 @@ class CAtmoConfig {
int getStaticColor_Blue() { return m_StaticColor_Blue; }
void setStaticColor_Blue(int value) { m_StaticColor_Blue=value; }
AtmoConnectionType getConnectionType() { return m_eAtmoConnectionType; }
void setConnectionType(AtmoConnectionType value) { m_eAtmoConnectionType = value; }
......@@ -258,7 +272,10 @@ class CAtmoConfig {
int getLiveView_EdgeWeighting() { return m_LiveView_EdgeWeighting; }
void setLiveView_EdgeWeighting(int value) { m_LiveView_EdgeWeighting=value; }
int getLiveView_BrightCorrect() { return m_LiveView_BrightCorrect; }
int getLiveView_RowsPerFrame() { return m_LiveView_RowsPerFrame; }
void setLiveView_RowsPerFrame(int value) { m_LiveView_RowsPerFrame=value; }
int getLiveView_BrightCorrect() { return m_LiveView_BrightCorrect; }
void setLiveView_BrightCorrect(int value) { m_LiveView_BrightCorrect=value; }
int getLiveView_DarknessLimit() { return m_LiveView_DarknessLimit; }
......@@ -312,7 +329,6 @@ class CAtmoConfig {
int getHardware_gamma_blue() { return m_Hardware_gamma_blue; }
void setHardware_gamma_blue(int value) { m_Hardware_gamma_blue=value; }
AtmoGammaCorrect getSoftware_gamma_mode() { return m_Software_gamma_mode; }
int getSoftware_gamma_red() { return m_Software_gamma_red; }
int getSoftware_gamma_green() { return m_Software_gamma_green; }
......@@ -359,6 +375,9 @@ class CAtmoConfig {
int getMoMo_Channels() { return m_MoMo_Channels; }
void setMoMo_Channels(int chCount) { m_MoMo_Channels = chCount; }
int getFnordlicht_Amount() { return m_Fnordlicht_Amount; }
void setFnordlicht_Amount(int fnordlichtAmount) { m_Fnordlicht_Amount = fnordlichtAmount; }
};
#endif
......@@ -114,7 +114,8 @@ enum AtmoConnectionType
actNUL = 3,
actMultiAtmo = 4,
actMondolight = 5,
actMoMoLight = 6
actMoMoLight = 6,
actFnordlicht = 7
};
static const char *AtmoDeviceTypes[] = {
"Atmo-Classic",
......@@ -123,10 +124,10 @@ static const char *AtmoDeviceTypes[] = {
"Nul-Device",
"Multi-Atmo",
"Mondolight",
"MoMoLight"
"MoMoLight",
"Fnordlicht"
};
#define ATMO_DEVICE_COUNT 7
#define ATMO_DEVICE_COUNT 8
#if defined(_ATMO_VLC_PLUGIN_)
enum EffectMode {
......
......@@ -13,6 +13,7 @@
#include "AtmoDmxSerialConnection.h"
#include "AtmoMultiConnection.h"
#include "MoMoConnection.h"
#include "FnordlichtConnection.h"
#include "AtmoExternalCaptureInput.h"
#include <math.h>
......@@ -27,7 +28,6 @@
# include "AtmoGdiDisplayCaptureInput.h"
#endif
CAtmoTools::CAtmoTools(void)
{
}
......@@ -40,7 +40,6 @@ void CAtmoTools::ShowShutdownColor(CAtmoDynData *pDynData)
{
pDynData->LockCriticalSection();
CAtmoConnection *atmoConnection = pDynData->getAtmoConnection();
CAtmoConfig *atmoConfig = pDynData->getAtmoConfig();
if((atmoConnection != NULL) && (atmoConfig!=NULL) && atmoConfig->isSetShutdownColor()) {
......@@ -403,6 +402,24 @@ ATMO_BOOL CAtmoTools::RecreateConnection(CAtmoDynData *pDynData)
return ATMO_TRUE;
}
case actFnordlicht: {
CFnordlichtConnection *tempConnection = new CFnordlichtConnection( atmoConfig );
if(tempConnection->OpenConnection() == ATMO_FALSE) {
pDynData->setAtmoConnection(tempConnection);
pDynData->UnLockCriticalSection();
return ATMO_FALSE;
}
pDynData->setAtmoConnection(tempConnection);
pDynData->ReloadZoneDefinitionBitmaps();
tempConnection->CreateDefaultMapping( atmoConfig->getChannelAssignment(0) );
CAtmoTools::SetChannelAssignment(pDynData, atmoConfig->getCurrentChannelAssignment() );
pDynData->UnLockCriticalSection();
return ATMO_TRUE;
}
default: {
pDynData->UnLockCriticalSection();
return ATMO_FALSE;
......
/*
* FnordlichtConnection.h: class to access a FnordlichtLight Hardware
* - the description could be found
* here: http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
*
* (C) Kai Lauterbach (klaute at gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id$
*/
#include "AtmoDefs.h"
#include "FnordlichtConnection.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "FnordlichtConfigDialog.h"
#endif
#include <stdio.h>
#include <fcntl.h>
#if !defined(WIN32)
#include <termios.h>
#include <unistd.h>
#endif
CFnordlichtConnection::CFnordlichtConnection(CAtmoConfig *cfg)
: CAtmoConnection(cfg)
{
m_hComport = INVALID_HANDLE_VALUE;
}
CFnordlichtConnection::~CFnordlichtConnection()
{
}
ATMO_BOOL CFnordlichtConnection::OpenConnection()
{
#if defined(_ATMO_VLC_PLUGIN_)
char *serdevice = m_pAtmoConfig->getSerialDevice();
if ( !serdevice )
return ATMO_FALSE;
#else
int portNummer = m_pAtmoConfig->getComport();
m_dwLastWin32Error = 0;
if ( portNummer < 1 )
return ATMO_FALSE; // make no real sense;-)
#endif
CloseConnection();
#if !defined(_ATMO_VLC_PLUGIN_)
char serdevice[16]; // com4294967295
sprintf(serdevice,"com%d",portNummer);
#endif
#if defined(WIN32)
m_hComport = CreateFile(serdevice,
GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if ( m_hComport == INVALID_HANDLE_VALUE )
{
// we have a problem here can't open com port...
// somebody else may use it?
// m_dwLastWin32Error = GetLastError();
return ATMO_FALSE;
}
/* change serial settings (Speed, stopbits etc.) */
DCB dcb; // fr comport-parameter
dcb.DCBlength = sizeof(DCB);
GetCommState(m_hComport, &dcb); // ger current serialport settings
dcb.BaudRate = 19200; // set speed
dcb.ByteSize = 8; // set databits
dcb.Parity = NOPARITY; // set parity
dcb.StopBits = ONESTOPBIT; // set one stop bit
SetCommState(m_hComport, &dcb); // apply settings
#else
int bconst = B19200;
m_hComport = open(serdevice,O_RDWR |O_NOCTTY);
if ( m_hComport < 0 )
return ATMO_FALSE;
struct termios tio;
memset(&tio,0,sizeof(tio));
tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
tio.c_iflag = (INPCK | BRKINT);
cfsetispeed(&tio, bconst);
cfsetospeed(&tio, bconst);
if( ! tcsetattr(m_hComport, TCSANOW, &tio) )
tcflush(m_hComport, TCIOFLUSH);
else {
// can't change parms
close(m_hComport);
m_hComport = -1;
return false;
}
#endif
// sync fnordlicht
if ( sync() )
// stop fading on all devices
if ( stop(255) )
return true; // fnordlicht initialized...
return false; // something is going wrong...
}
void CFnordlichtConnection::CloseConnection()
{
if ( m_hComport != INVALID_HANDLE_VALUE )
{
reset(255);
#if defined(WIN32)
CloseHandle(m_hComport);
#else
close(m_hComport);
#endif
m_hComport = INVALID_HANDLE_VALUE;
}
}
ATMO_BOOL CFnordlichtConnection::isOpen(void)
{
return (m_hComport != INVALID_HANDLE_VALUE);
}
ATMO_BOOL CFnordlichtConnection::HardwareWhiteAdjust(int global_gamma,
int global_contrast,
int contrast_red,
int contrast_green,
int contrast_blue,
int gamma_red,
int gamma_green,
int gamma_blue,
ATMO_BOOL storeToEeprom)
{
return ATMO_FALSE; //no hardware adjust required
}
/*
def fade_rgb(addr, r, g, b, step, delay)
$dev.write addr.chr
$dev.write "\x01"
$dev.write step.chr
$dev.write delay.chr
$dev.write r.chr
$dev.write g.chr
$dev.write b.chr
$dev.write "\x00\x00\x00\x00\x00"
$dev.write "\x00\x00\x00"
$dev.flush
end
*/
ATMO_BOOL CFnordlichtConnection::SendData(pColorPacket data)
{
if ( m_hComport == INVALID_HANDLE_VALUE )
return ATMO_FALSE;
int amount = getAmountFnordlichter();
unsigned char buffer[15];
memset(&buffer, 0, sizeof(buffer) ); // zero buffer
int iBytesWritten;
Lock();
buffer[1] = 0x01; // fade to rgb color
buffer[2] = 0x80; // in two steps
buffer[3] = 0x01; // 1ms pause between steps
// send all packages to all fnordlicht's
for( unsigned char i=0; i < amount; i++ )
{
int idx;
if ( m_ChannelAssignment && i < m_NumAssignedChannels )
idx = m_ChannelAssignment[i];
else
idx = -1; // no channel assigned to fnordlicht[i]
if( idx >= 0 && idx <= data->numColors )
{
// fnordlicht address equals to a MoMo Channel
buffer[0] = i; // fnordlicht address (0..254, 255 = broadcast)
buffer[4] = data->zone[idx].r;
buffer[5] = data->zone[idx].g;
buffer[6] = data->zone[idx].b;
}
#if defined(WIN32)
// send to COM-Port
WriteFile( m_hComport, buffer, sizeof(buffer),
(DWORD*)&iBytesWritten, NULL );
#else
iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
tcflush(m_hComport, TCIOFLUSH);
tcdrain(m_hComport); // flush buffer
#endif
if (iBytesWritten != sizeof(buffer))
{
Unlock();
return ATMO_FALSE; // shouldn't be...
}
}
Unlock();
return ATMO_TRUE;
}
ATMO_BOOL CFnordlichtConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
{
if ( !ca )
return ATMO_FALSE;
ca->setSize( getAmountFnordlichter() ); // oder 4 ? depending on config!
ca->setZoneIndex(0, 0); // Zone 5
ca->setZoneIndex(1, 1);
ca->setZoneIndex(2, 2);
ca->setZoneIndex(3, 3);
return ATMO_TRUE;
}
int CFnordlichtConnection::getAmountFnordlichter()
{
return m_pAtmoConfig->getFnordlicht_Amount();
}
/*
def sync(addr = 0)
1.upto(15) do
$dev.write "\e"
end
$dev.write addr.chr
$dev.flush
end
*/
ATMO_BOOL CFnordlichtConnection::sync(void)
{
if ( m_hComport == INVALID_HANDLE_VALUE )
return ATMO_FALSE;
unsigned char buffer[16];
int iBytesWritten;
Lock();
// fill buffer with 15 escape character
memset(&buffer, 0x1b, sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = 0x00; // append one zero byte
#if defined(WIN32)
// send to COM-Port
WriteFile( m_hComport, buffer, sizeof(buffer),
(DWORD*)&iBytesWritten, NULL );
#else
iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
tcflush(m_hComport, TCIOFLUSH);
tcdrain(m_hComport); // flush buffer
#endif
Unlock();
return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
}
/*
def stop(addr, fading = 1)
$dev.write addr.chr
$dev.write "\x08"
$dev.write fading.chr
$dev.write "\x00\x00\x00\x00"
$dev.write "\x00\x00\x00\x00\x00"
$dev.write "\x00\x00\x00"
$dev.flush
end
*/
ATMO_BOOL CFnordlichtConnection::stop(unsigned char addr)
{
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
unsigned char buffer[15];
memset(&buffer, 0, sizeof(buffer)); // zero buffer
int iBytesWritten;
Lock();
buffer[0] = addr; // fnordlicht address (255 = broadcast)
buffer[1] = 0x08; // stop command
buffer[2] = 1; // fading
#if defined(WIN32)
// send to COM-Port
WriteFile( m_hComport, buffer, sizeof(buffer),
(DWORD*)&iBytesWritten, NULL );
#else
iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
tcflush(m_hComport, TCIOFLUSH);
tcdrain(m_hComport); // flush buffer
#endif
Unlock();
return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
}
/*
*/
ATMO_BOOL CFnordlichtConnection::reset(unsigned char addr)
{
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
stop(255);
if ( sync() && start_bootloader(addr) )
{
#if defined(_ATMO_VLC_PLUGIN_)
do_sleep(200000); // wait 200ms
#else
do_sleep(200); // wait 200ms
#endif
if ( sync() && boot_enter_application(addr) )
return ATMO_TRUE;
}
return ATMO_FALSE;
}
/*
def start_bootloader(addr)
$dev.write(addr.chr)
$dev.write("\x80")
$dev.write("\x6b\x56\x27\xfc")
$dev.write("\x00\x00\x00\x00\x00\x00\x00\x00\x00")
$dev.flush
end
*/
ATMO_BOOL CFnordlichtConnection::start_bootloader(unsigned char addr)
{
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
unsigned char buffer[15];
memset(&buffer, 0, sizeof(buffer)); // zero buffer
int iBytesWritten;
Lock();
buffer[0] = addr; // fnordlicht address (255 = broadcast)
buffer[1] = 0x80; // start_bootloader
buffer[2] = 0x6b;
buffer[3] = 0x56;
buffer[4] = 0x27;
buffer[5] = 0xfc;
#if defined(WIN32)
// send to COM-Port
WriteFile( m_hComport, buffer, sizeof(buffer),
(DWORD*)&iBytesWritten, NULL );
#else
iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
tcflush(m_hComport, TCIOFLUSH);
tcdrain(m_hComport); // flush buffer
#endif
Unlock();
return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
}
/*
def boot_enter_application(addr)
$dev.write(addr.chr)
$dev.write("\x87")
$dev.write("\x00"*13)
$dev.flush
end
*/
ATMO_BOOL CFnordlichtConnection::boot_enter_application(unsigned char addr)
{
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
unsigned char buffer[15];
memset(&buffer, 0, sizeof(buffer)); // zero buffer
int iBytesWritten;
Lock();
buffer[0] = addr; // fnordlicht address (255 = broadcast)
buffer[1] = 0x87; // boot_ender_application command
#if defined(WIN32)
// send to COM-Port
WriteFile( m_hComport, buffer, sizeof(buffer),
(DWORD*)&iBytesWritten, NULL );
#else
iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
tcflush(m_hComport, TCIOFLUSH);
tcdrain(m_hComport); // flush buffer
#endif
Unlock();
return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
}
#if !defined(_ATMO_VLC_PLUGIN_)
char *CFnordlichtConnection::getChannelName(int ch)
{
char buf[60];
if( ch < 0 ) return NULL;
if( ch >= getAmountFnordlichter() ) return NULL;
sprintf(buf,"Number [%d]",ch);
return strdup(buf);
// sorry asprintf is not defined on Visual Studio :)
// return (asprintf(&ret, "Number [%d]", ch) != -1) ? ret : NULL;
}
ATMO_BOOL CFnordlichtConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent,
CAtmoConfig *cfg)
{
CFnordlichtConfigDialog *dlg = new CFnordlichtConfigDialog(hInst,
parent,
cfg);
INT_PTR result = dlg->ShowModal();
delete dlg;
if(result == IDOK)
return ATMO_TRUE;
else
return ATMO_FALSE;
}
#endif
/*
* FnordlichtConnection.h: class to access a FnordlichtLight Hardware
* - the description could be found
* here: http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
*
* (C) Kai Lauterbach (klaute at gmail.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id$
*/
#ifndef _FnordlichtConnection_h_
#define _FnordlichtConnection_h_
#include "AtmoDefs.h"
#include "AtmoConnection.h"
#include "AtmoConfig.h"
#if defined(WIN32)
# include <windows.h>
#endif
class CFnordlichtConnection : public CAtmoConnection
{
private:
HANDLE m_hComport;
ATMO_BOOL sync(void);
ATMO_BOOL stop(unsigned char addr);
ATMO_BOOL reset(unsigned char addr);
ATMO_BOOL start_bootloader(unsigned char addr);
ATMO_BOOL boot_enter_application(unsigned char addr);
#if defined(WIN32)
DWORD m_dwLastWin32Error;
public:
DWORD getLastError() { return m_dwLastWin32Error; }
#endif
public:
CFnordlichtConnection (CAtmoConfig *cfg);
virtual ~CFnordlichtConnection (void);
virtual ATMO_BOOL OpenConnection();
virtual void CloseConnection();
virtual ATMO_BOOL isOpen(void);
virtual ATMO_BOOL SendData(pColorPacket data);
virtual ATMO_BOOL HardwareWhiteAdjust(int global_gamma,
int global_contrast,
int contrast_red,
int contrast_green,
int contrast_blue,
int gamma_red,
int gamma_green,
int gamma_blue,
ATMO_BOOL storeToEeprom);
virtual int getAmountFnordlichter();
virtual const char *getDevicePath() { return "fnordlicht"; }
#if !defined(_ATMO_VLC_PLUGIN_)
virtual char *getChannelName(int ch);
virtual ATMO_BOOL ShowConfigDialog(HINSTANCE hInst, HWND parent,
CAtmoConfig *cfg);
#endif
virtual ATMO_BOOL CreateDefaultMapping(CAtmoChannelAssignment *ca);
};
#endif
This piece of software is based on the software and descriptions mentioned below -
(re)Written by: Igor / Atmo (aka André Weber) - WeberAndre@gmx.de
Matthiaz
MacGyver2k
if you need to contact one of us - come to www.vdr-portal.de
http://www.vdr-portal.de/board/thread.php?threadid=59294 -- Description and Development of the Windows Software
http://www.vdr-portal.de/board/thread.php?threadid=48574 -- Description and Development of the Hardware part
=====================================================
Info for Users on Vista or Windows 7 with active UAC!
=====================================================
for the first launch do it as Administrator with the following command line
AtmoWinA.exe /register
to create the required registry entries for the COM Objects, without
these registry entries - the DirectShow Filter and also the VLC Plugin
will not work.
If anything went fine you should see the message "COM Server registered Ok!".
See the file COPYING.txt for license information.
VideoLAN / VLC
---------------
In order to use this Programm with the VLC-Media-Player properly copy the "AtmoCtrlLib.dll" into the same Location where the vlc.exe is. E.G.: "D:\Programme\VLC".
NEWER Versions of VideoLAN 1.1.x and higher, don't need a own copy of the "AtmoCtrlLib.dll" in the vlc.exe folder,
if the complete filename of the AtmoWin*.exe is given. (Atmo Filter will try to load the DLL from there)
Then open VLC and navigate to "Extras" / "Settings" or Press "Ctrl" + "p".
Check that the radiobutton in the lower part of the dialogbox called "Show settings" -> "all" is checked.
Now open the Register "Video" and click on "Filter". There you have to select the checkbox "AtmoLight-Filter".
Afterwards you expand the Tree "Filter" in the Listbox on the left side. By selecting the entry "AtmoLight" you gain more settings.
The most important are right these one at the beginning:
VideoLAN 1.0.x
==============
"Use build in AtmoLight driver":
Using this Property means VLC will control the Hardware with its built in driver.
(no need for the extra AtmoWin software driver)
VideoLAN 1.1.x
==============
You have the following choices for "Devicetype" instead of the old settings
"AtmoWin Software" - is only available on Windows and works like the old way useing the external AtmoWin*.exe Software package, with the AtmoCtrlLib.dll.
"Classic AtmoLight" - is the same as the former "use build in AtmoLight driver"
"Quattro AtmoLight" - allows to use up to four serial connected class AtmoLight devices, as one logical device
"DMX" - allows to control a simple serial DMX devices for AtmoLight effects
"MoMoLight" - is a another kind of hardware supporting 2 oder 3 channels.
(see bottom of this file - for more infos about the devices.)
VideonLAN 1.0.x
===============
"Serial Device / Port":
The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using the Property
"use build in AtmoLight driver" )
VideonLAN 1.1.x
===============
"Serial Device / Port":
The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using a device
other than "AtmoWin Software")
in the case of the device "Quattro AtmoLight" you may specify up to four ports/devices seperated by
, or ; for example if you are useing two physical devices write
COM6;COM7 or on linux /dev/ttyUSB1;/dev/ttyUSB2
VideoLAN 1.0.x
==============
"Filename of AtmoWinA.exe":
The Path and the Name of the executable. E.G.:
'D:\atmoWin_0.45\AtmoWinA.exe' (Using this setting expects that you have copied "AtmoCtrlLib.dll" to the Path where VLC.exe is like described before)
VideoLAN 1.1.x
==============
"Filename of AtmoWinA.exe":
The Path and the Name of the executable. E.G.:
'D:\atmoWin_0.45\AtmoWinA.exe'
in the same path where the .exe resides the "AtmoCtrlLib.dll" should be there. or you may need to place
a copy of this ".dll" into the vlc.exe folder - like in VideoLAN 1.0.x
Afterwards you should apply those settings by pressing the button "Save".
VideoLAN 1.1.x - new options and settings
=========================================
Zone Layout for the build-in Atmo
=================================
This is the most important change I think - because the number of analyzed zones isn't
longer fixed to 4 or 5 - it allows to define the physical layout of your lights arround
the screen.
"Number of zones on top" -- how many light sources are place on top of the screen
(number of columns in which the screen should be tiled)
"Number of zones on bottom" -- how many light sources are place on bottom of the screen
(number of columns in which the screen should be tiled)
"Zones on left / right side" -- how many light sources are place on right/left of the screen
(number of rows in which the screen should be tiled)
its assumed that the number on right and left is equal.
"[] Calculate a average zone" -- define a color pair depending on the complete screen content
This settings tiles the screen into a number of zones - which get analyzed by atmoLight to
determine a most used color for these areas - each zone has a number starting from zero.
The zones are usualy numbered in clock-wise order starting at the top/left of the screen.
Example 1: classic Atmo with 4 channels
---------------------------------------
"Number of zones on top" = 1
"Number of zones on bottom" = 1
"Zones on left / right side" = 1
"[] Calculate a average zone" = false/0 not checked.
will produce this zone layout
-----------
| Zone 0 |
---------------------
| | | |
| Z | | Z |
| o | | o |
| n | | n |
| e | | e |
| | | |
| 3 | | 1 |
---------------- ----
| Zone 2 |
-----------
Example 2: classic Atmo with 4 channels
---------------------------------------
"Number of zones on top" = 2
"Number of zones on bottom" = 0
"Zones on left / right side" = 1
"[] Calculate a average zone" = false/0 not checked.
----------- -----------
| Zone 0 | | Zone 1 |
---------------------------------
| | | |
| Z | | Z |
| o | | o |
| n | | n |
| e | | e |
| | | |
| 3 | | 2 |
----- -----
Example 3: classic Atmo with 4 channels
---------------------------------------
"Number of zones on top" = 1
"Number of zones on bottom" = 0
"Zones on left / right side" = 1
"[X] Calculate a average zone" = true/1 checked.
-----------
| Zone 0 |
---------------------
| | -------- | |
| Z | | Z | | Z |
| o | | o | | o |
| n | | n | | n |
| e | | e | | e |
| | | 3 | | |
| 2 | -------- | 1 |
----- -----
Zone 3 - usualy calcuates the most used color of the full screen / picture / frame
not only at the border of the picture.
"The average zone" is allways the last in the sequence of numbers.
the weightning gradients for these zones are auto calculated
from 100% .. 0% starting from the edge.
thats also the cause why the parameters Channel assignment changed,
the classic comboboxes are still there for devices with 4 channels ot less,
but for newer devices the "Channel / Zone assignment" should be used which
is defined by a , or ; separated list of "AtmoLight channel numbers" if you
want to hide a calcuated zone from output - you can assign channel -1 to
do this.
for classic AtmoLight with "Example 1" you may write this:
-1;3;2;1;0
AtmoLight Channel 0: gets no zone assigned (-1)
AtmoLight Channel 1: gets zone 3 (left)
AtmoLight Channel 2: gets zone 2 (bottom)
AtmoLight Channel 3: gets zone 1 (right)
AtmoLight Channel 4: gets zone 0 (top)
Also the settings for Gradient images change for the new devices, its no longer
sufficient to speficy only 5 image name - because the number of zones is no longer
fixed to five.
So its prefered to set a path ("Gradient Bitmap searchpath"), where files
like "zone_0.bmp" "zone_1.bmp" etc. exists. (with the same rules as defined for
the old zone bitmaps.)
--> I think in most cases its no longer required to use this option,
to change the zone layout - for most cases its sufficient to change
"Zone Layout for the build-in Atmo" to get the same effect?
Live Set of parameters for Buildin AtmoLight
============================================
durring playback with the buildin driver you can now change some settings
of the filter without stopping / starting your movie - just open the
"extras" --> "Effects and Filters" --> [Video effects] --> [AtmoLight]
- move the sliders or change the calcuation mode, or enable/disable
the debug grid - just in time.
new Debugging Option
====================
[] Mark analyzed pixels - puts a grid of the used pixels on each frame
to see from which locations/positions the colors are extracted.
DMX Options
-----------
like the group says only for the DMX device
"Count of AtmoLight Channels" - defines how many RGB Channels should be simulated
with this DMX device (each RGB channel needs three DMX channels!)
"DMX adress for each channel" - defines the DMX Startadress for each AtmoLight
channel as "," or ";" separated list. (starting with 0 up to 252) it is assumed
that the f.e. of the DMX-AtmoLight channel starts at DMX-Channel 5 - that
DMX-Channel 5: is red
DMX-Channel 6: is green
DMX-Channel 7: is blue!
MoMoLight options
-----------------
"Count of channels" - defines the devicetype and serial protocol
3: - means 3 channels hardware
4: - means 4 channels hardware
(its required to set the correct number of channels to get this device working,
because the serial protocol isn't the same!)
VideoLan Options and Devices - the buildin version of AtmoLight supports a subset of the
devices that AtmoWin supports.
- AtmoWin Software - means do not use the VLC buildin video processing - just forward
the basic preprocessed data to the launched AtmoWinA.exe controlling your hardware.
- Classic AtmoLight - means the classic hardware from www.vdr-portal.de - with up to 5 channels.
- Quattro AtmoLight - is nothing else as that you have connected up to 4 "classic AtmoLight" devices
to your computer creating a up 16 channel Atmo Light - each devices needs its own serial port.
you have to write the ports seperated by , or ; to [Serial Port/device] f.e. COM3,COM4,COM5 or on
Linux /dev/ttyUSB01,/dev/ttyUSB02,/dev/ttyUSB03
- DMX - stands for a simple DMX controller which can control up to 255 DMX devices (lights)
- f.e. you may have a look here:
* http://www.dzionsko.de/elektronic/index.htm
* http://www.ulrichradig.de/ (search for dmx on his page)
- MoMoLight - is a serial device, with 3 or 4 channels - doing nearly the same like
Classic AtmoLight - just another protocol to control the hardware.
http://lx.divxstation.com/article.asp?aId=151
http://www.the-boss.dk/pages/momolight.htm
Original Readme - of the Linux Version - from where some code was used
to do the color calculations ...
######################################################################
Original Readme and Authors of the Linux VDR Plugin!
######################################################################
Written by: Eike Edener <vdr@edener.de>
Project's homepage: www.edener.de
Latest version available at: www.edener.de
See the file COPYING for license information.
----------------------------------------------------------------------
for detailed informations visit the VDR-Wiki:
http://www.vdr-wiki.de/wiki/index.php/Atmo-plugin
Development:
http://www.vdr-portal.de/board/thread.php?threadid=48574
Known bugs:
n/a
----------------------------------------------------------------------
This piece of software is based on the software and descriptions mentioned below -
(re)Written by: Igor / Atmo (aka André Weber) - WeberAndre@gmx.de
Matthiaz
MacGyver2k
if you need to contact one of us - come to www.vdr-portal.de
http://www.vdr-portal.de/board/thread.php?threadid=59294 -- Description and Development of the Windows Software
http://www.vdr-portal.de/board/thread.php?threadid=48574 -- Description and Development of the Hardware part
=====================================================
Info for Users on Vista or Windows 7 with active UAC!
=====================================================
for the first launch do it as Administrator with the following command line
AtmoWinA.exe /register
to create the required registry entries for the COM Objects, without
these registry entries - the DirectShow Filter and also the VLC Plugin
will not work.
If anything went fine you should see the message "COM Server registered Ok!".
See the file COPYING.txt for license information.
VideoLAN / VLC
---------------
In order to use this Programm with the VLC-Media-Player properly copy the "AtmoCtrlLib.dll" into the same Location where the vlc.exe is. E.G.: "D:\Programme\VLC".
NEWER Versions of VideoLAN 1.1.x and higher, don't need a own copy of the "AtmoCtrlLib.dll" in the vlc.exe folder,
if the complete filename of the AtmoWin*.exe is given. (Atmo Filter will try to load the DLL from there)
Then open VLC and navigate to "Extras" / "Settings" or Press "Ctrl" + "p".
Check that the radiobutton in the lower part of the dialogbox called "Show settings" -> "all" is checked.
Now open the Register "Video" and click on "Filter". There you have to select the checkbox "AtmoLight-Filter".
Afterwards you expand the Tree "Filter" in the Listbox on the left side. By selecting the entry "AtmoLight" you gain more settings.
The most important are right these one at the beginning:
VideoLAN 1.0.x
==============
"Use build in AtmoLight driver":
Using this Property means VLC will control the Hardware with its built in driver.
(no need for the extra AtmoWin software driver)
VideoLAN 1.1.x
==============
You have the following choices for "Devicetype" instead of the old settings
"AtmoWin Software" - is only available on Windows and works like the old way useing the external AtmoWin*.exe Software package, with the AtmoCtrlLib.dll.
"Classic AtmoLight" - is the same as the former "use build in AtmoLight driver"
"Quattro AtmoLight" - allows to use up to four serial connected class AtmoLight devices, as one logical device
"DMX" - allows to control a simple serial DMX devices for AtmoLight effects
"MoMoLight" - is a another kind of hardware supporting 2 oder 3 channels.
(see bottom of this file - for more infos about the devices.)
VideonLAN 1.0.x
===============
"Serial Device / Port":
The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using the Property
"use build in AtmoLight driver" )
VideonLAN 1.1.x
===============
"Serial Device / Port":
The COM-Port you are using for the hardware. E.G.: COM6 (This setting must be done if you are using a device
other than "AtmoWin Software")
in the case of the device "Quattro AtmoLight" you may specify up to four ports/devices seperated by
, or ; for example if you are useing two physical devices write
COM6;COM7 or on linux /dev/ttyUSB1;/dev/ttyUSB2
VideoLAN 1.0.x
==============
"Filename of AtmoWinA.exe":
The Path and the Name of the executable. E.G.:
'D:\atmoWin_0.45\AtmoWinA.exe' (Using this setting expects that you have copied "AtmoCtrlLib.dll" to the Path where VLC.exe is like described before)
VideoLAN 1.1.x
==============
"Filename of AtmoWinA.exe":
The Path and the Name of the executable. E.G.:
'D:\atmoWin_0.45\AtmoWinA.exe'
in the same path where the .exe resides the "AtmoCtrlLib.dll" should be there. or you may need to place
a copy of this ".dll" into the vlc.exe folder - like in VideoLAN 1.0.x
Afterwards you should apply those settings by pressing the button "Save".
VideoLAN 1.1.x - new options and settings
=========================================
Zone Layout for the build-in Atmo
=================================
This is the most important change I think - because the number of analyzed zones isn't
longer fixed to 4 or 5 - it allows to define the physical layout of your lights arround
the screen.
"Number of zones on top" -- how many light sources are place on top of the screen
(number of columns in which the screen should be tiled)
"Number of zones on bottom" -- how many light sources are place on bottom of the screen
(number of columns in which the screen should be tiled)
"Zones on left / right side" -- how many light sources are place on right/left of the screen
(number of rows in which the screen should be tiled)
its assumed that the number on right and left is equal.
"[] Calculate a average zone" -- define a color pair depending on the complete screen content
This settings tiles the screen into a number of zones - which get analyzed by atmoLight to
determine a most used color for these areas - each zone has a number starting from zero.
The zones are usualy numbered in clock-wise order starting at the top/left of the screen.
Example 1: classic Atmo with 4 channels
---------------------------------------
"Number of zones on top" = 1
"Number of zones on bottom" = 1
"Zones on left / right side" = 1
"[] Calculate a average zone" = false/0 not checked.
will produce this zone layout
-----------
| Zone 0 |
---------------------
| | | |
| Z | | Z |
| o | | o |
| n | | n |
| e | | e |
| | | |
| 3 | | 1 |
---------------- ----
| Zone 2 |
-----------
Example 2: classic Atmo with 4 channels
---------------------------------------
"Number of zones on top" = 2
"Number of zones on bottom" = 0
"Zones on left / right side" = 1
"[] Calculate a average zone" = false/0 not checked.
----------- -----------
| Zone 0 | | Zone 1 |
---------------------------------
| | | |
| Z | | Z |
| o | | o |
| n | | n |
| e | | e |
| | | |
| 3 | | 2 |
----- -----
Example 3: classic Atmo with 4 channels
---------------------------------------
"Number of zones on top" = 1
"Number of zones on bottom" = 0
"Zones on left / right side" = 1
"[X] Calculate a average zone" = true/1 checked.
-----------
| Zone 0 |
---------------------
| | -------- | |
| Z | | Z | | Z |
| o | | o | | o |
| n | | n | | n |
| e | | e | | e |
| | | 3 | | |
| 2 | -------- | 1 |
----- -----
Zone 3 - usualy calcuates the most used color of the full screen / picture / frame
not only at the border of the picture.
"The average zone" is allways the last in the sequence of numbers.
the weightning gradients for these zones are auto calculated
from 100% .. 0% starting from the edge.
thats also the cause why the parameters Channel assignment changed,
the classic comboboxes are still there for devices with 4 channels ot less,
but for newer devices the "Channel / Zone assignment" should be used which
is defined by a , or ; separated list of "AtmoLight channel numbers" if you
want to hide a calcuated zone from output - you can assign channel -1 to
do this.
for classic AtmoLight with "Example 1" you may write this:
-1;3;2;1;0
AtmoLight Channel 0: gets no zone assigned (-1)
AtmoLight Channel 1: gets zone 3 (left)
AtmoLight Channel 2: gets zone 2 (bottom)
AtmoLight Channel 3: gets zone 1 (right)
AtmoLight Channel 4: gets zone 0 (top)
Also the settings for Gradient images change for the new devices, its no longer
sufficient to speficy only 5 image name - because the number of zones is no longer
fixed to five.
So its prefered to set a path ("Gradient Bitmap searchpath"), where files
like "zone_0.bmp" "zone_1.bmp" etc. exists. (with the same rules as defined for
the old zone bitmaps.)
--> I think in most cases its no longer required to use this option,
to change the zone layout - for most cases its sufficient to change
"Zone Layout for the build-in Atmo" to get the same effect?
Live Set of parameters for Buildin AtmoLight
============================================
durring playback with the buildin driver you can now change some settings
of the filter without stopping / starting your movie - just open the
"extras" --> "Effects and Filters" --> [Video effects] --> [AtmoLight]
- move the sliders or change the calcuation mode, or enable/disable
the debug grid - just in time.
new Debugging Option
====================
[] Mark analyzed pixels - puts a grid of the used pixels on each frame
to see from which locations/positions the colors are extracted.
DMX Options
-----------
like the group says only for the DMX device
"Count of AtmoLight Channels" - defines how many RGB Channels should be simulated
with this DMX device (each RGB channel needs three DMX channels!)
"DMX adress for each channel" - defines the DMX Startadress for each AtmoLight
channel as "," or ";" separated list. (starting with 0 up to 252) it is assumed
that the f.e. of the DMX-AtmoLight channel starts at DMX-Channel 5 - that
DMX-Channel 5: is red
DMX-Channel 6: is green
DMX-Channel 7: is blue!
MoMoLight options
-----------------
"Count of channels" - defines the devicetype and serial protocol
3: - means 3 channels hardware
4: - means 4 channels hardware
(its required to set the correct number of channels to get this device working,
because the serial protocol isn't the same!)
VideoLan Options and Devices - the buildin version of AtmoLight supports a subset of the
devices that AtmoWin supports.
- AtmoWin Software - means do not use the VLC buildin video processing - just forward
the basic preprocessed data to the launched AtmoWinA.exe controlling your hardware.
- Classic AtmoLight - means the classic hardware from www.vdr-portal.de - with up to 5 channels.
- Quattro AtmoLight - is nothing else as that you have connected up to 4 "classic AtmoLight" devices
to your computer creating a up 16 channel Atmo Light - each devices needs its own serial port.
you have to write the ports seperated by , or ; to [Serial Port/device] f.e. COM3,COM4,COM5 or on
Linux /dev/ttyUSB01,/dev/ttyUSB02,/dev/ttyUSB03
- DMX - stands for a simple DMX controller which can control up to 255 DMX devices (lights)
- f.e. you may have a look here:
* http://www.dzionsko.de/elektronic/index.htm
* http://www.ulrichradig.de/ (search for dmx on his page)
- MoMoLight - is a serial device, with 3 or 4 channels - doing nearly the same like
Classic AtmoLight - just another protocol to control the hardware.
http://lx.divxstation.com/article.asp?aId=151
http://www.the-boss.dk/pages/momolight.htm
- Fnordlicht - is a serial device with up to four channels
http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
http://github.com/fd0/fnordlicht/
Original Readme - of the Linux Version - from where some code was used
to do the color calculations ...
######################################################################
Original Readme and Authors of the Linux VDR Plugin!
######################################################################
Written by: Eike Edener <vdr@edener.de>
Project's homepage: www.edener.de
Latest version available at: www.edener.de
See the file COPYING for license information.
----------------------------------------------------------------------
for detailed informations visit the VDR-Wiki:
http://www.vdr-wiki.de/wiki/index.php/Atmo-plugin
Development:
http://www.vdr-portal.de/board/thread.php?threadid=48574
Known bugs:
n/a
----------------------------------------------------------------------
......@@ -139,7 +139,8 @@ static const int pi_device_type_values[] = {
1, /* AtmoLight classic */
2, /* Quattro AtmoLight */
3, /* DMX Device */
4 /* MoMoLight device */
4, /* MoMoLight device */
5 /* fnordlicht */
};
static const char *const ppsz_device_type_descriptions[] = {
#if defined( WIN32 )
......@@ -148,7 +149,8 @@ static const char *const ppsz_device_type_descriptions[] = {
N_("Classic AtmoLight"),
N_("Quattro AtmoLight"),
N_("DMX"),
N_("MoMoLight")
N_("MoMoLight"),
N_("fnordlicht")
};
#define DMX_CHANNELS_TEXT N_("Count of AtmoLight channels")
......@@ -162,6 +164,11 @@ static const char *const ppsz_device_type_descriptions[] = {
#define MOMO_CHANNELS_LONGTEXT N_("Depending on your MoMoLight hardware " \
"choose 3 or 4 channels")
#define FNORDLICHT_AMOUNT_TEXT N_("Count of fnordlicht's")
#define FNORDLICHT_AMOUNT_LONGTEXT N_("Depending on the amount your " \
"fnordlicht hardware " \
"choose 1 to 4 channels")
#if defined( WIN32 )
# define DEFAULT_DEVICE 0
#else
......@@ -376,7 +383,7 @@ add_string(CFG_PREFIX "serialdev", "COM1", NULL,
add_file(CFG_PREFIX "atmowinexe", NULL, NULL,
ATMOWINEXE_TEXT, ATMOWINEXE_LONGTEXT, false )
#else
add_string(CFG_PREFIX "serialdev", "/dev/ttyS01", NULL,
add_string(CFG_PREFIX "serialdev", "/dev/ttyUSB0", NULL,
SERIALDEV_TEXT, SERIALDEV_LONGTEXT, false )
#endif
......@@ -421,6 +428,13 @@ set_section( N_("MoMoLight options" ), 0 )
add_integer_with_range(CFG_PREFIX "momo-channels", 3, 3, 4, NULL,
MOMO_CHANNELS_TEXT, MOMO_CHANNELS_LONGTEXT, false)
/* 2,2,4 means 2 is the default value, 1 minimum amount,
4 maximum amount
*/
set_section( N_("fnordlicht options" ), 0 )
add_integer_with_range(CFG_PREFIX "fnordlicht-amount", 2, 1, 4, NULL,
FNORDLICHT_AMOUNT_TEXT,
FNORDLICHT_AMOUNT_LONGTEXT, false)
/*
......@@ -652,6 +666,7 @@ static const char *const ppsz_filter_options[] = {
"dmx-channels",
"dmx-chbase",
"momo-channels",
"fnordlicht-amount",
#if defined(WIN32 )
"atmowinexe",
......@@ -1523,6 +1538,14 @@ static void Atmo_SetupConfig(filter_t *p_filter, CAtmoConfig *p_atmo_config)
p_atmo_config->setMoMo_Channels(
var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "momo-channels")
);
/*
fnordlicht options
*/
p_atmo_config->setFnordlicht_Amount(
var_CreateGetIntegerCommand( p_filter, CFG_PREFIX "fnordlicht-amount")
);
}
......@@ -1603,48 +1626,58 @@ static void Atmo_SetupParameters(filter_t *p_filter)
/* importing all required functions I hope*/
p_sys->pf_ctrl_atmo_initialize =
(int32_t (*)(void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoInitialize");
(int32_t (*)(void))GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoInitialize");
if(!p_sys->pf_ctrl_atmo_initialize)
msg_Err( p_filter, "export AtmoInitialize missing.");
p_sys->pf_ctrl_atmo_finalize =
(void (*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoFinalize");
(void (*)(int32_t))GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoFinalize");
if(!p_sys->pf_ctrl_atmo_finalize)
msg_Err( p_filter, "export AtmoFinalize missing.");
p_sys->pf_ctrl_atmo_switch_effect =
(int32_t(*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSwitchEffect");
(int32_t(*)(int32_t))GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoSwitchEffect" );
if(!p_sys->pf_ctrl_atmo_switch_effect)
msg_Err( p_filter, "export AtmoSwitchEffect missing.");
p_sys->pf_ctrl_atmo_set_live_source =
(int32_t(*)(int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSetLiveSource");
(int32_t(*)(int32_t))GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoSetLiveSource" );
if(!p_sys->pf_ctrl_atmo_set_live_source)
msg_Err( p_filter, "export AtmoSetLiveSource missing.");
p_sys->pf_ctrl_atmo_create_transfer_buffers =
(void (*)(int32_t, int32_t, int32_t , int32_t))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoCreateTransferBuffers");
(void (*)(int32_t, int32_t, int32_t , int32_t))
GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoCreateTransferBuffers" );
if(!p_sys->pf_ctrl_atmo_create_transfer_buffers)
msg_Err( p_filter, "export AtmoCreateTransferBuffers missing.");
p_sys->pf_ctrl_atmo_lock_transfer_buffer=
(uint8_t*(*) (void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoLockTransferBuffer");
(uint8_t*(*) (void))GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoLockTransferBuffer");
if(!p_sys->pf_ctrl_atmo_lock_transfer_buffer)
msg_Err( p_filter, "export AtmoLockTransferBuffer missing.");
p_sys->pf_ctrl_atmo_send_pixel_data =
(void (*)(void))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoSendPixelData");
(void (*)(void))GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoSendPixelData");
if(!p_sys->pf_ctrl_atmo_send_pixel_data)
msg_Err( p_filter, "export AtmoSendPixelData missing.");
p_sys->pf_ctrl_atmo_get_image_size =
(void (*)(int32_t*,int32_t*))GetProcAddress(p_sys->h_AtmoCtrl,"AtmoWinGetImageSize");
(void (*)(int32_t*,int32_t*))GetProcAddress( p_sys->h_AtmoCtrl,
"AtmoWinGetImageSize");
if(!p_sys->pf_ctrl_atmo_get_image_size)
msg_Err( p_filter, "export AtmoWinGetImageSize missing.");
} else {
/* the DLL is missing try internal filter ...*/
msg_Warn( p_filter, "AtmoCtrlLib.dll missing fallback to internal atmo classic driver");
msg_Warn( p_filter,
"AtmoCtrlLib.dll missing fallback to internal atmo classic driver" );
p_sys->i_device_type = 1;
}
}
......@@ -1684,6 +1717,10 @@ static void Atmo_SetupParameters(filter_t *p_filter)
p_sys->p_atmo_config->setConnectionType( actMoMoLight );
break;
case 5:
p_sys->p_atmo_config->setConnectionType( actFnordlicht );
break;
default:
msg_Warn( p_filter, "invalid device type %d found",
p_sys->i_device_type );
......@@ -2227,7 +2264,8 @@ static void CreateMiniImage( filter_t *p_filter, picture_t *p_inpic)
}
}
msg_Dbg( p_filter, "AtmoFrame %u Time: %d ms", p_sys->ui_frame_counter, mdate() / 1000);
msg_Dbg( p_filter, "AtmoFrame %u Time: %d ms", p_sys->ui_frame_counter,
mdate() / 1000);
p_sys->ui_frame_counter++;
#endif
......@@ -2532,7 +2570,7 @@ static int AtmoSettingsCallback( vlc_object_t *p_this, char const *psz_var,
);
if( !strcmp( psz_var, CFG_PREFIX "filtermode" ))
p_atmo_config->setLiveViewFilterMode( (AtmoFilterMode)newval.i_int);
p_atmo_config->setLiveViewFilterMode( (AtmoFilterMode)newval.i_int );
else if( !strcmp( psz_var, CFG_PREFIX "percentnew" ))
p_atmo_config->setLiveViewFilter_PercentNew( newval.i_int );
......@@ -2762,10 +2800,14 @@ static void atmo_parse_crop(char *psz_cropconfig,
i_crop_bottom = strtol( psz_end, &psz_end, 10 );
if( *psz_end != '\0' ) return;
i_width = fmt_render.i_visible_width - i_crop_left - i_crop_right;
i_width = fmt_render.i_visible_width -
i_crop_left -
i_crop_right;
i_visible_width = i_width;
i_height = fmt_render.i_visible_height - i_crop_top - i_crop_bottom;
i_height = fmt_render.i_visible_height -
i_crop_top -
i_crop_bottom;
i_visible_height = i_height;
i_x_offset = i_crop_left;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment