Commit bf2bdcca authored by Jérome Decoodt's avatar Jérome Decoodt

Add rotate-deciangle for more precision in rotate

Add unimotion (http://members.optusnet.com.au/lbramsay/programs/unimotion.html)
to motion interface
Add a low band filter to the motion
parent 22462d18
......@@ -173,6 +173,7 @@ case "${host_os}" in
VLC_ADD_LDFLAGS([mkv mp4], [-framework IOKit -framework CoreFoundation])
VLC_ADD_CFLAGS([libvlc vlc],[-x objective-c])
VLC_ADD_LDFLAGS([vlc],[-undefined dynamic_lookup])
VLC_ADD_LDFLAGS([motion],[-framework IOKit -framework CoreFoundation])
AC_ARG_ENABLE(macosx-defaults,
[ --enable-macosx-defaults Build the default configuration on Mac OS X (default enabled)])
if test "x${enable_macosx_defaults}" != "xno"
......@@ -3330,7 +3331,6 @@ AS_IF([test "${enable_libtar}" != "no"],[
] )
])
dnl
dnl A52/AC3 decoder plugin
dnl
......
......@@ -6,5 +6,14 @@ SOURCES_ntservice = ntservice.c
SOURCES_hotkeys = hotkeys.c
SOURCES_lirc = lirc.c
SOURCES_rc = rc.c
SOURCES_motion = motion.c
SOURCES_dbus = dbus.c dbus.h
if HAVE_DARWIN
motion_extra = unimotion.c unimotion.h
else
motion_extra = $(NULL)
endif
SOURCES_motion = \
motion.c \
$(motion_extra) \
$(NULL)
/*****************************************************************************
* motion.c: control VLC with laptop built-in motion sensors
*****************************************************************************
* Copyright (C) 2006 the VideoLAN team
* Copyright (C) 2006 - 2007 the VideoLAN team
* $Id$
*
* Author: Sam Hocevar <sam@zoy.org>
* Jérôme Decoodt <djc@videolan.org> (unimotion integration)
*
* 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
......@@ -26,6 +27,7 @@
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <math.h>
#include <vlc/vlc.h>
#include <vlc_interface.h>
......@@ -35,12 +37,17 @@
# include <unistd.h>
#endif
#ifdef __APPLE__
#include "unimotion.h"
#endif
/*****************************************************************************
* intf_sys_t: description and status of interface
*****************************************************************************/
struct intf_sys_t
{
enum { NO_SENSOR, HDAPS_SENSOR, AMS_SENSOR } sensor;
enum { NO_SENSOR, HDAPS_SENSOR, AMS_SENSOR, UNIMOTION_SENSOR } sensor;
enum sms_hardware unimotion_hw;
int i_calibrate;
......@@ -110,6 +117,10 @@ int Open ( vlc_object_t *p_this )
/* Apple Motion Sensor support */
p_intf->p_sys->sensor = AMS_SENSOR;
}
#ifdef __APPLE__
else if( p_intf->p_sys->unimotion_hw = detect_sms() )
p_intf->p_sys->sensor = UNIMOTION_SENSOR;
#endif
else
{
/* No motion sensor support */
......@@ -136,14 +147,17 @@ void Close ( vlc_object_t *p_this )
/*****************************************************************************
* RunIntf: main loop
*****************************************************************************/
#define FILTER_LENGTH 16
#define LOW_THRESHOLD 800
#define HIGH_THRESHOLD 1000
static void RunIntf( intf_thread_t *p_intf )
{
int i_x, i_oldx = 0;
int i_x, i_oldx = 0, i_sum = 0, i = 0;
int p_oldx[FILTER_LENGTH];
memset( p_oldx, 0, FILTER_LENGTH * sizeof( int ) );
while( !intf_ShouldDie( p_intf ) )
{
#define LOW_THRESHOLD 80
#define HIGH_THRESHOLD 100
vout_thread_t *p_vout;
const char *psz_filter, *psz_type;
vlc_bool_t b_change = VLC_FALSE;
......@@ -152,6 +166,10 @@ static void RunIntf( intf_thread_t *p_intf )
msleep( INTF_IDLE_SLEEP );
i_x = GetOrientation( p_intf );
i_sum += i_x - p_oldx[i];
p_oldx[i++] = i_x;
if( i == FILTER_LENGTH ) i = 0;
i_x = i_sum / FILTER_LENGTH;
if( p_intf->p_sys->b_use_rotate )
{
......@@ -162,7 +180,8 @@ static void RunIntf( intf_thread_t *p_intf )
vlc_object_find_name( p_intf->p_libvlc, "rotate", FIND_CHILD );
if( p_obj )
{
var_SetInteger( p_obj, "rotate-angle",((360+i_x/2)%360) );
var_SetInteger( p_obj, "rotate-deciangle",
((3600+i_x/2)%3600) );
i_oldx = i_x;
vlc_object_release( p_obj );
}
......@@ -209,14 +228,17 @@ static void RunIntf( intf_thread_t *p_intf )
i_oldx = i_x;
}
}
#undef FILTER_LENGTH
#undef LOW_THRESHOLD
#undef HIGH_THRESHOLD
/*****************************************************************************
* GetOrientation: get laptop orientation, range -180 / +180
* GetOrientation: get laptop orientation, range -1800 / +1800
*****************************************************************************/
static int GetOrientation( intf_thread_t *p_intf )
{
FILE *f;
int i_x, i_y;
int i_x, i_y, i_z;
switch( p_intf->p_sys->sensor )
{
......@@ -231,7 +253,7 @@ static int GetOrientation( intf_thread_t *p_intf )
fscanf( f, "(%d,%d)", &i_x, &i_y );
fclose( f );
return i_x - p_intf->p_sys->i_calibrate;
return ( i_x - p_intf->p_sys->i_calibrate ) * 10;
case AMS_SENSOR:
f = fopen( "/sys/devices/ams/x", "r" );
......@@ -243,8 +265,23 @@ static int GetOrientation( intf_thread_t *p_intf )
fscanf( f, "%d", &i_x);
fclose( f );
return - i_x * 3; /* FIXME: arbitrary */
return - i_x * 30; /* FIXME: arbitrary */
#ifdef __APPLE__
case UNIMOTION_SENSOR:
if( read_sms_raw( p_intf->p_sys->unimotion_hw, &i_x, &i_y, &i_z ) )
{
double d_norm = sqrt( i_x*i_x+i_z*i_z );
if( d_norm < 100 )
return 0;
double d_x = i_x / d_norm;
if( i_z > 0 )
return -asin(d_x)*3600/3.141;
else
return 3600 + asin(d_x)*3600/3.141;
}
#endif
else
return 0;
default:
return 0;
}
......
/*
* UniMotion - Unified Motion detection for Apple portables.
*
* Copyright (c) 2006 Lincoln Ramsay. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation Inc. 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
*/
/*
* HISTORY of Motion
* Written by Christian Klein
* Modified for iBook compatibility by Pall Thayer
* Modified for Hi Res Powerbook compatibility by Pall Thayer
* Modified for MacBook Pro compatibility by Randy Green
* Disparate forks unified into UniMotion by Lincoln Ramsay
*/
// This license applies to the portions created by Cristian Klein.
/* motion.c
*
* a little program to display the coords returned by
* the powerbook motion sensor
*
* A fine piece of c0de, brought to you by
*
* ---===---
* *** teenage mutant ninja hero coders ***
* ---===---
*
* All of the software included is copyrighted by Christian Klein <chris@5711.org>.
*
* Copyright 2005 Christian Klein. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author must not be used to endorse or promote
* products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifdef __APPLE__
#include "unimotion.h"
#include <IOKit/IOKitLib.h>
#include <CoreFoundation/CoreFoundation.h>
#include <string.h>
#include <stdint.h>
enum data_type {
PB_IB,
MBP
};
struct pb_ib_data {
int8_t x;
int8_t y;
int8_t z;
int8_t pad[57];
};
struct mbp_data {
int16_t x;
int16_t y;
int16_t z;
int8_t pad[34];
};
union motion_data {
struct pb_ib_data pb_ib;
struct mbp_data mbp;
};
static int set_values(int type, int *kernFunc, char **servMatch, int *dataType)
{
switch ( type ) {
case powerbook:
*kernFunc = 21;
*servMatch = "IOI2CMotionSensor";
*dataType = PB_IB;
break;
case ibook:
*kernFunc = 21;
*servMatch = "IOI2CMotionSensor";
*dataType = PB_IB;
break;
case highrespb:
*kernFunc = 21;
*servMatch = "PMUMotionSensor";
*dataType = PB_IB;
break;
case macbookpro:
*kernFunc = 5;
*servMatch = "SMCMotionSensor";
*dataType = MBP;
break;
default:
return 0;
}
return 1;
}
static int probe_sms(int kernFunc, char *servMatch, int dataType, void *data)
{
kern_return_t result;
mach_port_t masterPort;
io_iterator_t iterator;
io_object_t aDevice;
io_connect_t dataPort;
IOItemCount structureInputSize;
IOByteCount structureOutputSize;
union motion_data inputStructure;
union motion_data *outputStructure;
outputStructure = (union motion_data *)data;
result = IOMasterPort(MACH_PORT_NULL, &masterPort);
CFMutableDictionaryRef matchingDictionary = IOServiceMatching(servMatch);
result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator);
if (result != KERN_SUCCESS) {
//fputs("IOServiceGetMatchingServices returned error.\n", stderr);
return 0;
}
aDevice = IOIteratorNext(iterator);
IOObjectRelease(iterator);
if (aDevice == 0) {
//fputs("No motion sensor available\n", stderr);
return 0;
}
result = IOServiceOpen(aDevice, mach_task_self(), 0, &dataPort);
IOObjectRelease(aDevice);
if (result != KERN_SUCCESS) {
//fputs("Could not open motion sensor device\n", stderr);
return 0;
}
switch ( dataType ) {
case PB_IB:
structureInputSize = sizeof(struct pb_ib_data);
structureOutputSize = sizeof(struct pb_ib_data);
break;
case MBP:
structureInputSize = sizeof(struct mbp_data);
structureOutputSize = sizeof(struct mbp_data);
break;
default:
return 0;
}
memset(&inputStructure, 0, sizeof(union motion_data));
memset(outputStructure, 0, sizeof(union motion_data));
result = IOConnectMethodStructureIStructureO(dataPort, kernFunc, structureInputSize,
&structureOutputSize, &inputStructure, outputStructure);
IOServiceClose(dataPort);
if (result != KERN_SUCCESS) {
//puts("no coords");
return 0;
}
return 1;
}
int detect_sms()
{
int kernFunc;
char *servMatch;
int dataType;
union motion_data data;
int i;
for ( i = 1; ; i++ ) {
if ( !set_values(i, &kernFunc, &servMatch, &dataType) )
break;
if ( probe_sms(kernFunc, servMatch, dataType, &data) )
return i;
}
return unknown;
}
int read_sms_raw(int type, int *x, int *y, int *z)
{
int kernFunc;
char *servMatch;
int dataType;
union motion_data data;
if ( !set_values(type, &kernFunc, &servMatch, &dataType) )
return 0;
if ( probe_sms(kernFunc, servMatch, dataType, &data) ) {
switch ( dataType ) {
case PB_IB:
if ( x ) *x = data.pb_ib.x;
if ( y ) *y = data.pb_ib.y;
if ( z ) *z = data.pb_ib.z;
break;
case MBP:
if ( x ) *x = data.mbp.x;
if ( y ) *y = data.mbp.y;
if ( z ) *z = data.mbp.z;
break;
default:
return 0;
}
return 1;
}
return 0;
}
int read_sms(int type, int *x, int *y, int *z)
{
int _x, _y, _z;
int xoff, yoff, zoff;
Boolean ok;
int ret;
ret = read_sms_raw(type, &_x, &_y, &_z);
if ( !ret )
return 0;
static CFStringRef app = CFSTR("com.ramsayl.UniMotion");
static CFStringRef xoffstr = CFSTR("x_offset");
static CFStringRef yoffstr = CFSTR("y_offset");
static CFStringRef zoffstr = CFSTR("z_offset");
xoff = CFPreferencesGetAppIntegerValue(xoffstr, app, &ok);
if ( ok ) _x += xoff;
yoff = CFPreferencesGetAppIntegerValue(yoffstr, app, &ok);
if ( ok ) _y += yoff;
zoff = CFPreferencesGetAppIntegerValue(zoffstr, app, &ok);
if ( ok ) _z += zoff;
*x = _x;
*y = _y;
*z = _z;
return ret;
}
int read_sms_real(int type, double *x, double *y, double *z)
{
int _x, _y, _z;
int xscale, yscale, zscale;
int ret;
Boolean ok;
ret = read_sms_raw(type, &_x, &_y, &_z);
if ( !ret )
return 0;
static CFStringRef app = CFSTR("com.ramsayl.UniMotion");
static CFStringRef xscalestr = CFSTR("x_scale");
static CFStringRef yscalestr = CFSTR("y_scale");
static CFStringRef zscalestr = CFSTR("z_scale");
xscale = CFPreferencesGetAppIntegerValue(xscalestr, app, &ok);
if ( !ok ) return 0;
yscale = CFPreferencesGetAppIntegerValue(yscalestr, app, &ok);
if ( !ok ) return 0;
zscale = CFPreferencesGetAppIntegerValue(zscalestr, app, &ok);
if ( !ok ) return 0;
*x = _x / (double)xscale;
*y = _y / (double)yscale;
*z = _z / (double)zscale;
return 1;
}
#endif
/*
* UniMotion - Unified Motion detection for Apple portables.
*
* Copyright (c) 2006 Lincoln Ramsay. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation Inc. 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
*/
#ifndef UNIMOTION_H
#define UNIMOTION_H
#ifdef __cplusplus
extern "C" {
#endif
// The various SMS hardware that unimotion supports
enum sms_hardware {
unknown = 0,
powerbook = 1,
ibook = 2,
highrespb = 3,
macbookpro = 4
};
// prototypes for the functions in unimotion.c
// returns the value of SMS hardware present or unknown if no hardware is detected
int detect_sms();
// use the value returned from detect_sms as the type
// these functinos return 1 on success and 0 on failure
// they modify x, y and z if they are not 0
// raw, unmodified values
int read_sms_raw(int type, int *x, int *y, int *z);
// "calibrated" values (same as raw if no calibration data exists)
int read_sms(int type, int *x, int *y, int *z);
// real (1.0 = 1G) values (requires calibration data)
// note that this is the preferred API as it need not change with new machines
// however, this API does not work if no "scale" calibration data exists
int read_sms_real(int type, double *x, double *y, double *z);
#ifdef __cplusplus
}
#endif
#endif
......@@ -46,6 +46,10 @@ static int RotateCallback( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *p_data );
static int PreciseRotateCallback( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *p_data );
#define ANGLE_TEXT N_("Angle in degrees")
#define ANGLE_LONGTEXT N_("Angle in degrees (0 to 359)")
......@@ -84,7 +88,7 @@ struct filter_sys_t
static inline void cache_trigo( int i_angle, int *i_sin, int *i_cos )
{
const double f_angle = (((double)i_angle)*M_PI)/180.;
const double f_angle = (((double)i_angle)*M_PI)/1800.;
*i_sin = (int)(sin( f_angle )*256.);
*i_cos = (int)(cos( f_angle )*256.);
}
......@@ -110,8 +114,10 @@ static int Create( vlc_object_t *p_this )
p_filter->p_cfg );
p_sys->i_angle = var_CreateGetIntegerCommand( p_filter,
FILTER_PREFIX "angle" );
FILTER_PREFIX "angle" ) * 10;
var_CreateGetIntegerCommand( p_filter, FILTER_PREFIX "deciangle" );
var_AddCallback( p_filter, FILTER_PREFIX "angle", RotateCallback, p_sys );
var_AddCallback( p_filter, FILTER_PREFIX "deciangle", PreciseRotateCallback, p_sys );
cache_trigo( p_sys->i_angle, &p_sys->i_sin, &p_sys->i_cos );
......@@ -219,6 +225,20 @@ static int RotateCallback( vlc_object_t *p_this, char const *psz_var,
filter_sys_t *p_sys = (filter_sys_t *)p_data;
if( !strcmp( psz_var, "rotate-angle" ) )
{
p_sys->i_angle = newval.i_int*10;
cache_trigo( p_sys->i_angle, &p_sys->i_sin, &p_sys->i_cos );
}
return VLC_SUCCESS;
}
static int PreciseRotateCallback( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *p_data )
{
filter_sys_t *p_sys = (filter_sys_t *)p_data;
if( !strcmp( psz_var, "rotate-deciangle" ) )
{
p_sys->i_angle = newval.i_int;
......
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