From 1af1e3b16f2c70d802e5155efd38823756ca1be9 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Tue, 1 Jun 2010 21:26:36 +0200 Subject: [PATCH] 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/ MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: André Weber --- modules/video_filter/Modules.am | 1 + modules/video_filter/atmo/AtmoConfig.cpp | 98 ++- modules/video_filter/atmo/AtmoConfig.h | 35 +- modules/video_filter/atmo/AtmoDefs.h | 9 +- modules/video_filter/atmo/AtmoTools.cpp | 21 +- .../atmo/FnordlichtConnection.cpp | 464 ++++++++++++++ .../video_filter/atmo/FnordlichtConnection.h | 88 +++ modules/video_filter/atmo/README.txt | 595 +++++++++--------- modules/video_filter/atmo/atmo.cpp | 74 ++- 9 files changed, 1051 insertions(+), 334 deletions(-) create mode 100644 modules/video_filter/atmo/FnordlichtConnection.cpp create mode 100644 modules/video_filter/atmo/FnordlichtConnection.h diff --git a/modules/video_filter/Modules.am b/modules/video_filter/Modules.am index b6c13773de..ea46c31c68 100644 --- a/modules/video_filter/Modules.am +++ b/modules/video_filter/Modules.am @@ -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 diff --git a/modules/video_filter/atmo/AtmoConfig.cpp b/modules/video_filter/atmo/AtmoConfig.cpp index ec6c519587..e5273ddd57 100644 --- a/modules/video_filter/atmo/AtmoConfig.cpp +++ b/modules/video_filter/atmo/AtmoConfig.cpp @@ -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; + +} diff --git a/modules/video_filter/atmo/AtmoConfig.h b/modules/video_filter/atmo/AtmoConfig.h index 656c20ed72..d3dd961e50 100644 --- a/modules/video_filter/atmo/AtmoConfig.h +++ b/modules/video_filter/atmo/AtmoConfig.h @@ -19,11 +19,10 @@ # include #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 diff --git a/modules/video_filter/atmo/AtmoDefs.h b/modules/video_filter/atmo/AtmoDefs.h index ed48e880f3..739978a6fd 100644 --- a/modules/video_filter/atmo/AtmoDefs.h +++ b/modules/video_filter/atmo/AtmoDefs.h @@ -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 { diff --git a/modules/video_filter/atmo/AtmoTools.cpp b/modules/video_filter/atmo/AtmoTools.cpp index 69e07739cc..e96bb32315 100644 --- a/modules/video_filter/atmo/AtmoTools.cpp +++ b/modules/video_filter/atmo/AtmoTools.cpp @@ -13,6 +13,7 @@ #include "AtmoDmxSerialConnection.h" #include "AtmoMultiConnection.h" #include "MoMoConnection.h" +#include "FnordlichtConnection.h" #include "AtmoExternalCaptureInput.h" #include @@ -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; diff --git a/modules/video_filter/atmo/FnordlichtConnection.cpp b/modules/video_filter/atmo/FnordlichtConnection.cpp new file mode 100644 index 0000000000..583a1651db --- /dev/null +++ b/modules/video_filter/atmo/FnordlichtConnection.cpp @@ -0,0 +1,464 @@ +/* + * 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 +#include + +#if !defined(WIN32) +#include +#include +#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; // für 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 + diff --git a/modules/video_filter/atmo/FnordlichtConnection.h b/modules/video_filter/atmo/FnordlichtConnection.h new file mode 100644 index 0000000000..6a3fa13c36 --- /dev/null +++ b/modules/video_filter/atmo/FnordlichtConnection.h @@ -0,0 +1,88 @@ +/* + * 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 +#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 diff --git a/modules/video_filter/atmo/README.txt b/modules/video_filter/atmo/README.txt index 4cf6595960..44f568944a 100644 --- a/modules/video_filter/atmo/README.txt +++ b/modules/video_filter/atmo/README.txt @@ -1,296 +1,299 @@ -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 -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 +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 + +---------------------------------------------------------------------- diff --git a/modules/video_filter/atmo/atmo.cpp b/modules/video_filter/atmo/atmo.cpp index addb87c8e6..0bdc467983 100644 --- a/modules/video_filter/atmo/atmo.cpp +++ b/modules/video_filter/atmo/atmo.cpp @@ -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; -- 2.39.2