Building an applause-o-meter with a WS1361
1)The task
When a friend asked me if I could build an applause-o-meter (clap-o-meter, clapometer, applausemeter) for a concert, I thought that should be quick and painless. - I was wrong.But not knowing what one is up against can be a blessing. And so it went:
Detail of the application: Progress bars as bargraphs |
2) The Hardware
So I bought the cheapest sound level meter I could find at my favourite Chinese seller that sported an USB interface: The Wensn WS1361, also sold as HY1361.See this article about the driver setup to get it up and running with the original software in this blog post.
The other things needed for the applause-o-meter are a projector and a computer running a current version of Windows.
3) The software
For my purposes, the supplied software is pretty useless. So I set out to write my own software for reading the meter.3.1 libusb-win32 vs libusb
While the SoundPCLink software relies on libusb-win32, I found a fantastic project for using the libusb at libusb.info. Full support for Visual Studio 2017. - Very handy.You need to change the driver for the WS1361 from libusb-win32 to libusb (Winusb) with Zadig.
Change the driver with Zadig |
3.2 Simple c++ sound level reader
After a little time it took to understand the library, I wrote a very simple command line tool to read a single db value from the meter: /*
* ReadSoundMeter: Read DB Value from WS1361 / HY1361 sound level meter
* 2018-09 by AReResearch (Andy Reischle)
* www.areresearch.net
* Inspiration and many lines of code taken from
* Pete Batard <pete@akeo.ie> 's example code to libusb, xusb.c
*/
#include "pch.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <C:\Buffer\SoundMeter\libusb-master\libusb\libusb.h>
#define CALL_CHECK_CLOSE(fcall, hdl) do { int _r=fcall; if (_r < 0) { libusb_close(hdl); ERR_EXIT(_r); } } while (0)
#define ERR_EXIT(errcode) do { perr(" %s\n", libusb_strerror((enum libusb_error)errcode)); return -1; } while (0)
#if defined(_WIN32)
#define msleep(msecs) Sleep(msecs)
#else
#include <time.h>
#define msleep(msecs) nanosleep(&(struct timespec){msecs / 1000, (msecs * 1000000) % 1000000000UL}, NULL);
#endif
// Future versions of libusb will use usb_interface instead of interface
// in libusb_config_descriptor => cater for that
#define usb_interface interface
int r;
static uint16_t VID = 0x16C0;
static uint16_t PID = 0x05DC;
static void perr(char const *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
static double test_device(uint16_t vid, uint16_t pid)
{
uint8_t resultat[2];
libusb_device_handle *handle;
handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
if (handle == NULL) {
perr(" Failed.\n");
return -1;
}
r = libusb_control_transfer(handle, 0xC0, 0x04, 0, 0, resultat, sizeof(resultat), 1000);
if (r < 0) {
fprintf(stderr, "Error during control transfer: %s\n",
libusb_error_name(r));
}
libusb_close(handle);
return ((resultat[0] + ((resultat[1] & 3) * 256)) * 0.1 + 30);
}
int main(int argc, char** argv)
{
libusb_context *ctx = NULL; //a libusb session
r = libusb_init(NULL);
if (r < 0)
return r;
}
printf("%f\n", test_device(VID, PID));
libusb_exit(NULL);
}
3.3 And some visual basic
Writing a Windows forms application in C++ turned out a lot harder than expected. It feels like Microsoft had never even intended that to go smoothly.So I took an extremely ugly approach to call the above command line tool and read it's output into a visual basic windows forms application. The way I did that eats half the CPU power of a brand new i5 machine.
But I needed a quick solution. After the better half of a night of coding, I had a working version.
applause-o-meter GUI (German) |
The audience can "vote" one of the three pieces of each group to be played fully that evening.
4) The performance
A few brief words explaining voting procedure was all that it took. This was the first time that had been done in church music, and as a part of a city-wide, cultural event, it was received very well by the audience.Showing the results after the performance |
PS: The visual basic code is quite ugly and needs some tidying before publication. If you are in dire need of a clap-o-meter, please leave a note in the comments and I will make the code available regardless of it's shortcomings.
Intersting WS1361 links:
- Troy Simpson did a in-depth analysis of the WS1361 sound level meter's USB protocol on his web site www.ebswift.com/reverse-engineering-spl-usb.html
- There is a very cool arduino project with an arduino teensy and a usb host shield on this Chinese web site. This helped me a lot!
- Project on Github using Python running on Linux
- Manufacturer's product web site
- I bought the meter here from Banggood
- Here is a link to my own driver install instructions for the WS1361 (more secure)
No comments:
Post a Comment