pyUSB - delayed sending to the device? - buffer

I have an ESC printer.
I made a simple script to send data to the device, but after changing the content of the script - 1x the previous version of the subtitles is printed, and then, when called again, the current one.
As if the data from the USB was cached somewhere.
How can I make some FLUSH?
test.py
usb_= Connector(showUsbDevices=False)
usb_.send(b'I LOVE YOU')
connector:
class Connector:
def __init__(self, idVendor=0x0123, idProduct=0x1234, showUsbDevices=False):
self.idVendor = idVendor
self.idProduct = idProduct
if showUsbDevices:
pass
self.device = self.FindAndConnect()
if self.device is not None:
#if self.device.is_kernel_driver_active(0):
#self.device.detach_kernel_driver(0)
#self.device.detach_kernel_driver(1)
self.device.reset()
self.device.set_configuration()
self.cfg = self.device.get_active_configuration()
data_itfs = list(usb.util.find_descriptor(self.cfg, find_all=True,custom_match=lambda e: (e.bInterfaceClass == 0xA)))
intf = data_itfs[0]
self.device.set_interface_altsetting(intf)
itf_num = intf.bInterfaceNumber
print ("inf descriptor:===============", intf)
print("numer:===============",itf_num)
self.messageOut = usb.util.find_descriptor(intf, custom_match=lambda e: not (e.bEndpointAddress & 0x80))
self.messageIn = usb.util.find_descriptor(intf, custom_match=lambda e: (e.bEndpointAddress & 0x80))
#print(">>>>>>>>>>>>>>>>>>>Message Out",self.messageOut)
#print(">>>>>>>>>>>>>>>>>>>Message In",self.messageIn)
#print(repr(self.cfg))
def __del__(self):
if self.device is not None:
usb.util.dispose_resources(self.device)
def send(self, data):
#print ("endpoint_out",self.messageOut)
if self.device is not None:
print(data.decode("IBM852"))
self.messageOut.write(data)
#self.device.write(1,data,100)
#dane = self.messageIn.read(300)
#print("IN|->",dane)
def FindAndConnect(self):
device=usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
if device is None:
raise ValueError('Not found idVendor 0x%04x i idProduct 0x%04x' % (self.idVendor,self.idProduct))
print('Printer found idVendor 0x%04x i idProduct 0x%04x.... ' %(self.idVendor,self.idProduct))
return device
so when I run a test script that says
I LOVE YOU
I get
ILOVE YOU
when I change the inscription to
I HATE YOU and run the script
another copy is printed I LOVE YOU
and only the next start-up gives: I HATE YOU
What is it? Where's the bug?

I found it! Its:
self.device.reset() at finalizer:
def __del__(self):
if self.device is not None:
self.device.reset() ############### <<<< THIS IS THE KEY>>>> (added to all code)
usb.util.dispose_resources(self.device)

Related

ROS fail to publish to a different message type

I wrote a node called translater that basically doesn't do anything except for translating one message type to another.
It subscribes to a the topic pose_before and publishes to another topic pose_after.
The topic pose_before is of message type "PoseWithCovarianceStamped" and pose_after is "TransformStamped".
The issue is that all values in pose_after remain 0 when they're being published, but when I try to print the values inside the callback they do respond correctly.
#!/usr/bin/env python
import rospy
from geometry_msgs.msg import PoseWithCovarianceStamped
from geometry_msgs.msg import TransformStamped
def callback(data):
TransformStamped().transform.translation.x = data.pose.pose.position.x
TransformStamped().transform.translation.y = data.pose.pose.position.y
TransformStamped().transform.translation.z = data.pose.pose.position.z
TransformStamped().transform.rotation.x = data.pose.pose.orientation.x
TransformStamped().transform.rotation.y = data.pose.pose.orientation.y
TransformStamped().transform.rotation.z = data.pose.pose.orientation.z
TransformStamped().transform.rotation.w = data.pose.pose.orientation.w
def listener():
pub = rospy.Publisher('pose_after', TransformStamped, queue_size=40)
pose_after = TransformStamped()
rospy.init_node('translater', anonymous=True)
rospy.loginfo("Publishing pose_after")
rospy.Subscriber('pose_before', PoseWithCovarianceStamped, callback)
rate = rospy.Rate(40)
pose_after.header.stamp = rospy.Time.now()
pose_after.child_frame_id = 'base_footprint'
print(pose_after.transform.translation.x) # this prints (0,0)
while not rospy.is_shutdown():
pub.publish(pose_after)
rate.sleep()
if __name__ == '__main__':
try:
listener()
except rospy.ROSInterruptException:
pass
When I put the print line in callback then it actually is able to print the correct values, so I'm wondering why the values are lost outside of the callback. I've also tried assigning a global variable inside the callback but still didn't work.

Using AKSampleDescriptor

Using AKSamplerDescriptor
I am using an adapted AKSampler example, in which I try to use the sforzando output of Fluid.sf3 melodicSounds. Sforzando creates .sfz files for each instrument, but all pointing for the global sample to a huge .wav file.
In all the instrument.sfz files there is an offset and endpoint description for the part of the wave file to be used.
When I load the .sfz file I get a crash due to memory problems. It seems that for every defined region in the .sfz file the complete .wav file (140 mB) is loaded again.
The most likely is that loading the sample file with the AKSampleDescriptor as done in the AKSampler example will ignore offset and endpoint (AKSampleDescriptor.startPoint and AKSampleDescriptor.endPoint) while reloading the complete .wav file.
Is there a way to load just the part start-to-end wanted from the sample file, because the complete file has al the sample data for all the instruments (I know and use polyphony that extracts only one instrument at the time and works fine, but this is for other use)
Or, and that seems the best to me, just load the file once and than have the sampledescriptors point to the data in memory
Good suggestions, Rob. I just ran into this one-giant-WAV issue myself, having never seen it before. I was also using Sforzando for conversion. I'll look into adding the necessary capabilities to AKSampler. In the meantime, it might be easier to write a program to cut up the one WAV file into smaller pieces and adjust the SFZ accordingly.
Here is some Python 2.7 code to do this, which I have used successfully with a Sforzando-converted sf2 soundfont. It might need changes to work for you--there is huge variability among sfz files--but at least it might help you get started. This code requires the PyDub library for manipulating WAV audio.
import os
import re
from pydub import AudioSegment
def stripComments(text):
def replacer(match):
s = match.group(0)
if s.startswith('/'):
return " " # note: a space and not an empty string
else:
return s
pattern = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE
)
return re.sub(pattern, replacer, text)
def updateSplitList(splitList, regionLabels, values):
if len(values) > 3:
start = int(values['offset'])
length = int(values['end']) - start
name = regionLabels.pop(0)
splitList.add((name, start, length))
def lookupSplitName(splitList, offset, end):
for (name, start, end) in splitList:
if offset == start and end == end:
return name
return None
def outputGroupAndRegion(outputFile, splitList, values):
if values.has_key('lokey') and values.has_key('hikey') and values.has_key('pitch_keycenter'):
outputFile.write('<group> lokey=%s hikey=%s pitch_keycenter=%s\n' % (values['lokey'], values['hikey'], values['pitch_keycenter']))
elif values.has_key('key') and values.has_key('pitch_keycenter'):
outputFile.write('<group> key=%s pitch_keycenter=%s\n' % (values['key'], values['pitch_keycenter']))
if len(values) > 3:
outputFile.write(' <region> ')
if values.has_key('lovel') and values.has_key('hivel'):
outputFile.write('lovel=%s hivel=%s ' % (values['lovel'], values['hivel']))
if values.has_key('tune'):
outputFile.write('tune=%s ' % values['tune'])
if values.has_key('volume'):
outputFile.write('volume=%s ' % values['volume'])
if values.has_key('offset'):
outputFile.write('offset=0 ')
if values.has_key('end'):
outputFile.write('end=%d ' % (int(values['end']) - int(values['offset'])))
if values.has_key('loop_mode'):
outputFile.write('loop_mode=%s ' % values['loop_mode'])
if values.has_key('loop_start'):
outputFile.write('loop_start=%d ' % (int(values['loop_start']) - int(values['offset'])))
if values.has_key('loop_end'):
outputFile.write('loop_end=%d ' % (int(values['loop_end']) - int(values['offset'])))
outputFile.write('sample=samples/%s' % lookupSplitName(splitList, int(values['offset']), int(values['end'])) + '.wav\n')
def process(inputFile, outputFile):
# create a list of region labels
regionLabels = list()
for line in open(inputFile):
if line.strip().startswith('region_label'):
regionLabels.append(line.strip().split('=')[1])
# read entire input SFZ file
sfz = open(inputFile).read()
# strip comments and create a mixed list of <header> tags and key=value pairs
sfz_list = stripComments(sfz).split()
inSection = "none"
default_path = ""
global_sample = None
values = dict()
splitList = set()
# parse the input SFZ data and build up splitList
for item in sfz_list:
if item.startswith('<'):
inSection = item
updateSplitList(splitList, regionLabels, values)
values.clear()
continue
elif item.find('=') < 0:
#print 'unknown:', item
continue
key, value = item.split('=')
if inSection == '<control>' and key == 'default_path':
default_path = value.replace('\\', '/')
elif inSection == '<global>' and key == 'sample':
global_sample = value.replace('\\', '/')
elif inSection == '<region>':
values[key] = value
# split the wav file
bigWav = AudioSegment.from_wav(global_sample)
#print "%d channels, %d bytes/sample, %d frames/sec" % (bigWav.channels, bigWav.sample_width, bigWav.frame_rate)
frate = float(bigWav.frame_rate)
for (name, start, length) in splitList:
startMs = 1000 * start / frate
endMs = 1000 * (start + length) / frate
wav = bigWav[startMs : endMs]
wavName = 'samples/' + name + '.wav'
wav.export(wavName, format='wav')
# parse the input SFZ data again and generate the output SFZ
for item in sfz_list:
if item.startswith('<'):
inSection = item
outputGroupAndRegion(outputFile, splitList, values)
values.clear()
continue
elif item.find('=') < 0:
#print 'unknown:', item
continue
key, value = item.split('=')
if inSection == '<control>' and key == 'default_path':
default_path = value.replace('\\', '/')
elif inSection == '<global>' and key == 'sample':
global_sample = value.replace('\\', '/')
elif inSection == '<region>':
values[key] = value
dirPath = '000'
fileNameList = os.listdir(dirPath)
for fileName in fileNameList:
if fileName.endswith('.sfz'):
inputFile = os.path.join(dirPath, fileName)
outputFile = open(fileName, 'w')
print fileName
process(inputFile, outputFile)

Getting input report in pywinusb

I am using pywinusb to send/get data from Custom HID device. I can successfully send data but cant get it. Any suggestions? I tried to debug using Microsoft Message Analyzer and can see the data there but not in the script. Product/Vendor Ids, report id etc are correct.
Here the code,
from pywinusb import hid
from time import sleep
devicefilter = hid.HidDeviceFilter(vendor_id=0x0483, product_id=0x572A)
devices = devicefilter.get_devices()
print ("devices:", devices)
hid_device = devices[0]
print ("hid_device:", hid_device)
hid_device.open()
out_report = hid_device.find_output_reports()
in_report = hid_device.find_input_reports()
print("out_report:", out_report)
print("out_report[0]:",out_report[0])
print("in_report:", in_report)
print("in_report[0]:",in_report[0])
txBuffer = [0x55] * 64
txBuffer[0] = 0x01 # Report ID
rxBuffer = [0x00] * 64
rxBuffer[0] = 0x02 # Report ID
print(txBuffer)
print(rxBuffer)
out_report[0].set_raw_data(txBuffer)
in_report[0].set_raw_data(rxBuffer)
while 1:
out_report[0].send()
rxBuffer = in_report[0].get()
print("rxBuffer:", rxBuffer)
sleep(1)
hid_device.close()
I'm no expert on this my self but I have a similar sounding application Here is what I do. I don't explicitly create an input report but rather attach an input report handler to the usb receive buffer.
import pywinusb.hid as hid
# handler called when a report is received
def rx_handler(data):
print 'recv: ', data
def scan_hiddevice():
""" Scans for and returns the HID device. """
devices = hid.HidDeviceFilter( vendor_id = vendor_id).get_devices()
if not devices:
print "scan_hiddevice: No device connected."
return None
else:
device = devices[0]
#print("scan_hiddevice: found %s", device )
return device
return None
def setup_hiddevice():
"""Creates a new HID device, opens it and attaches a receive data handler"""
hid_device = scan_hiddevice()
hid_device.open()
hid_device.set_raw_data_handler(rx_handler)
return hid_device
def main(verbose=True):
hid_device = setup_hiddevice()
while (True):
#wait for data
I hope this can be of some use.

vlc lua: how do I get the full path of the current playing item?

I'm not a programmer so this is difficult for me. I want to make an extension to send the full path to the clipboard in the full format. Example:
D:\MyFolder\music\audio.mp3
I recently found and butchered this extension which sends the running time to the clipboard. Is it possible to modify it so it gets the full path instead of the running time?
I'm using VLC media player 2.0.5 Twoflower 32 bits.
Windows 7 professional 32bits SP1
Here's the content of the .lua file I'm using and want to modify:
-- Time2Clip.lua -- VLC extension --
--[[
INSTALLATION:
Put the file in the VLC subdir /lua/extensions, by default:
* Windows (all users): %ProgramFiles%\VideoLAN\VLC\lua\extensions\
Restart the VLC.
Then you simply use the extension by going to the "View" menu and selecting it.
--]]
function descriptor()
return {
title = "Time2Clip";
version = "1.0";
author = "valuex";
url = 'https://forum.videolan.org/viewtopic.php?f=29&t=101114';
shortdesc = "Time2Clip";
description = "<div style=\"background-color:lightgreen;\"><b>just a simple VLC extension </b></div>";
capabilities = {"input-listener"}
}
end
function activate()
create_dialog()
end
function close()
vlc.deactivate()
end
function create_dialog()
w = vlc.dialog("Time2Clip")
--w2 = w:add_button("Save_to_Clip", click_SAVE,2,1,1,1)
click_SAVE()
end
function click_SAVE()
local input = vlc.object.input()
if input then
local curtime=vlc.path()
-- local curtime=vlc.var.get(input, "time")
-- w2:set_text( curtime )
save_to_clipboard(curtime)
end
end
function save_to_clipboard(var)
strCmd = 'echo '..var..' |clip'
os.execute(strCmd)
vlc.deactivate()
end
I read LUA's README.TXT file and found this but I don't know how to use it. Please help me. Thanks in advance.
input.item(): Get the current input item. Input item methods are:
:uri(): Get item's URI.
:name(): Get item's name.
How about:
function descriptor()
return {
title = "URI2Clip";
version = "1.0";
author = "";
url = '';
shortdesc = "URI2Clip";
description = "<div><b>Copy the media URI to the Windows clipboard</b></div>";
}
end
function activate()
local item = vlc.input.item()
local uri = item:uri()
uri = string.gsub(uri, '^file:///', '')
uri = string.gsub(uri, '/', '\\')
strCmd = 'echo '..uri..' |clip'
os.execute(strCmd)
end
URI returns something like file:///c:/users/username/Documents/song.mp3 so I convert that to c:\users\username... format instead. NB. This is only going to work for saved files, it will mangle web addresses.

How to parse text in Groovy

I need to parse a text (output from a svn command) in order to retrieve a number (svn revision).
This is my code. Note that I need to retrieve all the output stream as a text to do other operations.
def proc = cmdLine.execute() // Call *execute* on the strin
proc.waitFor() // Wait for the command to finish
def output = proc.in.text
//other stuff happening here
output.eachLine {
line ->
def revisionPrefix = "Last Changed Rev: "
if (line.startsWith(revisionPrefix)) res = new Integer(line.substring(revisionPrefix.length()).trim())
}
This code is working fine, but since I'm still a novice in Groovy, I'm wondering if there were a better idiomatic way to avoid the ugly if...
Example of svn output (but of course the problem is more general)
Path: .
Working Copy Root Path: /svn
URL: svn+ssh://svn.company.com/opt/svnserve/repos/project/trunk
Repository Root: svn+ssh://svn.company.com/opt/svnserve/repos
Repository UUID: 516c549e-805d-4d3d-bafa-98aea39579ae
Revision: 25447
Node Kind: directory
Schedule: normal
Last Changed Author: ubi
Last Changed Rev: 25362
Last Changed Date: 2012-11-22 10:27:00 +0000 (Thu, 22 Nov 2012)
I've got inspiration from the answer below and I solved using find(). My solution is:
def revisionPrefix = "Last Changed Rev: "
def line = output.readLines().find { line -> line.startsWith(revisionPrefix) }
def res = new Integer(line?.substring(revisionPrefix.length())?.trim()?:"0")
3 lines, no if, very clean
One possible alternative is:
def output = cmdLine.execute().text
Integer res = output.readLines().findResult { line ->
(line =~ /^Last Changed Rev: (\d+)$/).with { m ->
if( m.matches() ) {
m[ 0 ][ 1 ] as Integer
}
}
}
Not sure it's better or not. I'm sure others will have different alternatives
Edit:
Also, beware of using proc.text. if your proc outputs a lot of stuff, then you could end up blocking when the inputstream gets full...
Here is a heavily commented alternative, using consumeProcessOutput:
// Run the command
String output = cmdLine.execute().with { proc ->
// Then, with a StringWriter
new StringWriter().with { sw ->
// Consume the output of the process
proc.consumeProcessOutput( sw, System.err )
// Make sure we worked
assert proc.waitFor() == 0
// Return the output (goes into `output` var)
sw.toString()
}
}
// Extract the version from by looking through all the lines
Integer version = output.readLines().findResult { line ->
// Pass the line through a regular expression
(line =~ /Last Changed Rev: (\d+)/).with { m ->
// And if it matches
if( m.matches() ) {
// Return the \d+ part as an Integer
m[ 0 ][ 1 ] as Integer
}
}
}

Resources