Replace AEAddressDesc in apple event - macos-carbon

I have an apple event, and I need to resend this event to the other process. Can anyone tell me how?
static void GetEvent(AppleEvent *event)
{
RgnHandle cursorRgn = NULL;
Boolean gotEvent;
gotEvent = WaitNextEvent(everyEvent, event, 32767L, cursorRgn);
if (gotEvent)
// AEProcessAppleEvent(event);
}
int main(int argc, char *argv[])
{
ProcessSerialNumber psn;
AppleEvent event;
GetEvent(&event);
GetProcessForPID([childProcess processIdentifier], &psn);
}
Thanks.

AEAddressDesc is a type, so your question as stated doesn't make sense.
What you're really asking to do is set the address of an event. That's an attribute; namely, the keyAddressAttr attribute. Set it as you would any other attribute of an Apple Event descriptor.

Related

gtk 3.0 use the same callback for several switches

I'm creating a Linux GUI using GTK3.0 and C and I want to use the same callback for several switches. In order to differentiate the switch that was clicked, I am trying to use the gpointer argument in g_signal_connect, but the callback doesn't seem to receive the right value.
I create the signals this way:
g_signal_connect(led1_switch, "state-set", G_CALLBACK(on_gpio_btn_click), (gpointer)"LED1");
g_signal_connect(led2_switch, "state-set", G_CALLBACK(on_gpio_btn_click), (gpointer)"LED2");
And the callback tries to get the gpointer passed:
static void on_gpio_btn_click(GtkWidget *wid, gpointer ptr)
{
int gpio;
int val = 0;
char *gpio_switch = ptr;
...
But when I debug the application, the ptr pointer has the value 0x1, a wrong memory address.
Shouldn't it point to the memory address where the constant string "LED1" is stored?
what am I doing wrong? How can I share the same callback for several widgets? I have 8 switches to control GPIOs and I would prefer to have one callback for all of them instead of creating eight.
Your function signature is wrong: the 2nd argument is the value of the switch's state, as can be found in the documentation of the "state-set" signal. That's also the reason why the value is 1: that's the actual value of TRUE.
In other words, your callback will like this:
static void on_gpio_btn_click(GtkSwitch *swtch, gboolean state, gpointer ptr)
{
int gpio;
int val = 0;
char *gpio_switch = ptr;
// ...
}

QAudioInput record sounds failed

For my purpose, I want to use Qt5.1 to record sounds in WAV format, 16000Hz, 16bit and 1 channel, but the sounds are all 32bit by default. So I must find a class that can set "Bit Size" and the class is QAudioFormat for there's a function setBitSize() in the class. So I can no longer use QAudioRecorder class for it can not take QAudioFormat as parameter but QAudioInput do. And I use QAudioInput to record sounds with the code below:
#include<QAudioFormat>
#include<QAudioInput>
#include<QString>
#include<QFile>
#include<QDebug>
int main()
{
QFile output;
output.setFileName("record.raw");
output.open(QIODevice::WriteOnly);
QAudioFormat settings;
settings.setCodec("audio/PCM");
settings.setSampleRate(16000);
settings.setSampleSize(16);
settings.setChannelCount(1);
settings.setByteOrder(QAudioFormat::LittleEndian);
settings.setSampleType(QAudioFormat::UnSignedInt);
QAudioInput *audio=new QAudioInput(settings);
audio->start(&output);
sleep(3);
audio->stop();
output.close();
delete audio;
return 0;
}
Well, after the program ran, the record.wav was still empty. I have successfully recorded the sounds using QAudioRecorder, and the only different is the QAudioRecorder class has setAudioInput() function (ie. "audio->setAudioInput("alsa:default");). So I think maybe it's the point of the problem, but QAudioInput has no function like this. That's my problem, maybe you can give my some advice and Thanks a lot:-)
I'm glad to have found someone with the same issue as mine. I've been trying to record from a microphone with QAudioRecorder but with a different sample size for a few days already. Thanks to your example I've succeeded by getting rid of QAudioRecorder. So it's my turn to help you.
I think while the program is in the sleep function it's not recording anymore. You need to use the concept of signal and slots provided by Qt to to record while the timer is running.
#include "AudioInput.h"
void AudioInput::setup(){
output.setFileName("record.raw");
output.open(QIODevice::WriteOnly);
QAudioFormat settings;
settings.setCodec("audio/PCM");
settings.setSampleRate(16000);
settings.setSampleSize(16);
settings.setChannelCount(1);
settings.setByteOrder(QAudioFormat::LittleEndian);
settings.setSampleType(QAudioFormat::UnSignedInt);
audio=new QAudioInput(settings);
audio->start(&output);
QTimer::singleShot(3000, this, SLOT(terminateRecording()));
}
void AudioInput::terminateRecording(){
audio->stop();
output.close();
delete audio;
}
I put your code in one class called AudioInput and the only difference is that I replaced sleep(3000) by QTimer::singleShot(3000, this, SLOT(terminateRecording()));. Contrary to sleep this function won't freeze the program during 3s but will just send a signal to terminateRecording() at the end of the time.
Here is the rest of the code:
int main(int argc, char** argv){
QCoreApplication app(argc,argv);
AudioInput t;
t.setup();
app.exec();
return 0;
}
and the header:
class AudioInput : public QObject{
Q_OBJECT
public Q_SLOTS:
void terminateRecording();
public:
void setup();
private:
QAudioInput *audio;
QFile output;
};
so basically the problem you seem to have is that the backend does not support the settings that you try to push into the QAudioInput. Luckily Qt has a way of getting the nearest usable format and here's hot to set it:
void AudioInput::setup(){
output.setFileName("record.raw");
output.open(QIODevice::WriteOnly);
QAudioFormat settings;
settings.setCodec("audio/PCM");
settings.setSampleRate(16000);
settings.setSampleSize(16);
settings.setChannelCount(1);
settings.setByteOrder(QAudioFormat::LittleEndian);
settings.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(settings)) {
settings = info.nearestFormat(settings); // This is the magic line
settings.setSampleRate(16000);
qDebug() << "Raw audio format not supported by backend. Trying the nearest format.";
}
audio=new QAudioInput(settings);
audio->start(&output);
QTimer::singleShot(3000, this, SLOT(terminateRecording()));
}

Update value after passing pointer

I am using a TCP server to send a char array. The function send() takes a char *, but, before that, it has to listen and accept a connection. Given that, I want to send the most recent data when an incoming connection is accepted. Previously, I used two threads. One updated the value in the buffer, the other simply waited for connections, then sent data.
I understand that there can be problems with not locking a mutex, but aside from that, would this same scheme work if I passed the char * to a send function, rather than updating it as a global variable?
Some code to demonstrate:
#include <pthread.h>
char buf[BUFLEN];
void *updateBuffer(void *arg) {
while(true) {
getNewData(buf);
}
}
void *sendData(void *arg) {
//Setup socket
while(true) {
newfd = accept(sockfd, (struct sockaddr *)&their_addr, &size);
send(newfd, buf, BUFLEN, 0);
close(newfd);
}
}
This would send the updated values whenever a new connection was established.
I want to try this:
#include <pthread.h>
char buf[BUFLEN];
void *updateBuffer(void *arg) {
while(true) {
getNewData(buf);
}
}
void *sendData(void *arg) {
TCPServer tcpServer;
while(true) {
tcpServer.send(buf);
}
}
Where the function tcpServer.send(char *) is basically the same as sendData() above.
The reason for doing this is so that I can make the TCP server into a class, since I'll need to use the same code elsewhere.
From my understanding, since I am passing the pointer, it's basically the same as when I just call send(), since I also pass a pointer there. The value will continue to update, but the address won't change, so it should work. Please let me know if that is correct. I'm also open to new ways of doing this (without mutex locks, preferably).
Yes, that is the way most of us do a send, pass a pointer to a buffer either void * or char *
I would coded like this:
int sendData(const char * buffer, const int length)
{
Socket newfd;
Int NumOfConnects=0;
while ((newfd=accept(sockfd, (struct sockaddr *)&their_addr, &size)) > 0)
{
// It would be necessary here to lock the buffer with a Mutex
send(newfd, buffer, length, 0);
// Release the Mutex
close(newfd);
NumOfConnects++;
}
// there is an error in the accept
// this could be OK,
// if the main thread has closed the sockfd socket indicating us to quit.
// returns the number of transfers we have done.
return NumOfConnects;
}
One thing to consider about using a pointer to a buffer which is modify in another thread; Could it be that in the middle of a send the buffer changes and the data sent is not accurate.
But that situation you've already noticed as well. Using a Mutex is suggested as you indicated.

Does QThread::quit() discard all events in EventQueue?

There is main function:
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
Worker w;
QObject::connect(&w, SIGNAL(done()), &a, SLOT(quit()), Qt::QueuedConnection);
w.start();
int ret = a.exec();
w.quit();
w.wait();
return ret;
}
And there is Worker's definition:
class Worker : public QThread
{
Q_OBJECT
public:
Worker(QObject *parent=0);
protected:
void run();
protected slots:
void process_request();
private:
int ttl;
Messenger* messenger;
}
Worker::Worker(QObject * parent)
:QThread(parent),
ttl(5),
messenger(new Messenger(this))
{
moveToThread(this);
connect(messenger, SIGNAL(new_message()), SLOT(process_request()), Qt::QueuedConnection);
}
void Worker::finish(){
quit();
messenger->disconnectFromNetwork();
}
void Worker::run(){
messenger->connectToNetwork("somewhere");
exec();
emit done();
}
void Worker::process_request(){
net_message msg;
messenger->recv(msg);
// PROCESSING
messenger->send(msg);
BOOST_LOG_SEV(file_log, severity::notification) << "TTL = " << ttl;
if (--ttl == 0) {
finish();
}
}
Well, sorry for the long exposition. The idea was that the Messenger lives in the main thread, and pokes the Worker when it has a new message for it, and the Worker lives only a certain amount of messages, after which it stops and shuts down entire application.
But there is a problem: the log file has lines TTL = -1, and TTL = -2, and such. It shouldn't, and the only reason I can think about is that quit() doesn't quite ends the event loop: it allows pending events to be processed before returning from exec(). Is it so? If "no", then what may cause such a behaviour?
First of all "You're doing that wrong".
Secondly documentation doesn't say what is the state of queue in event loop after exit was called. It is possible that exec() returns after event queue is empty to make sure that all asynchronous cleanups are done (in case if this it top most event loop, in this case it is).
edit:
I've checked source code. Apparently QEventLoop::processEvents is call between each check that event loop should exit. So it looks like exec() returns only when queue is empty.

How to avoid "Video Source -> Capture source" selection in OpenCV 2.3.0 - Visual C++ 2008

I had a perfectly working OpenCV code (having the function cvCaptureFromCAM(0)). But when I modified it to run in a separate thread, I get this "Video Source" selection dialog box and it asks me to choose the Webcam. Even though I select a cam, it appears that the function cvCaptureFromCAM(0) returns null. I also tried by passing the values 0, -1,1, CV_CAP_ANYto this function. I have a doubt that this dialog box causes this issue. Is there any way to avoid this or does anyone have any other opinion?
I've followed the following posts when debugging:
cvCreateCameraCapture returns null
OpenCV cvCaptureFromCAM returns zero
EDIT
Code structure
//header includes
CvCapture* capture =NULL;
IplImage* frame = NULL;
int main(int argc, char** argv){
DWORD qThreadID;
HANDLE ocvThread = CreateThread(0,0,startOCV, NULL,0, &qThreadID);
initGL(argc, argv);
glutMainLoop();
CloseHandle(ocvThread);
return 0;
}
void initGL(int argc, char** argv){
//Initialize GLUT
//Create the window
//etc
}
DWORD WINAPI startOCV(LPVOID vpParam){
//capture = cvCaptureFromCAM(0); //0 // CV_CAP_ANY
if ((capture = cvCaptureFromCAM(1)) == NULL){ // same as simply using assert(capture)
cerr << "!!! ERROR: vCaptureFromCAM No camera found\n";
return -1;
}
frame = cvQueryFrame(capture);
}
//other GL functions
Thanks.
Since this is a problem that only happens on Windows, an easy fix is to leave cvCaptureFromCAM(0) on the main() thread and then do the image processing stuff on a separate thread, as you intented originally.
Just declare CvCapture* capture = NULL; as a global variable so all your threads can access it.
Solved. I couldn't get rid of the above mentioned dialog box, but I avoided the error by simply duplicating the line capture = cvCaptureFromCAM(0);
capture = cvCaptureFromCAM(0);
capture = cvCaptureFromCAM(0);
It was just random. I suspect it had something to do with behavior of Thread. What's your idea?
Thanks all for contributing.

Resources