I'm writing an application that will time mouse latency for our product.
The way it works is that it sends a mouse movement, and measures the time between then and when we get a pixel change on screen.
Why does this delay affect the program.
int check_for_pixel_change() {
// Gets the pixels R value
unsigned char value = *((unsigned char *) (0x100));
// If this delay is not here then the loop will always return 1
usleep(5);
if(value == (0x80)) return 0;
else return 1;
}
int main() {
// Send move / start timer
while(check_for_pixel_change());
// stop timer
return 0;
}
Here is the code that worked.
Thanks to #barak-manos && #santosh-a.
I needed to change the char to volatile because it would be constantly changing by a different program.
int check_for_pixel_change() {
// Gets the pixels R value
volatile unsigned char value = *(volatile unsigned char *) (0x100);
if(value == (0x80)) return 0;
else return 1;
}
int main() {
// Send move / start timer
while(check_for_pixel_change());
// stop timer
return 0;
}
Related
Here's a pseudo-code(ish) that I'm trying to build.
This is the interrupt function. When switch 2 is pressed, the potval = 1. When switch 3 is pressed, potval = 2. Every time the switch is pressed, the potval is updated.
void interruptJ_function (void){ //if i change to int interruptJ_function, it says that it was expecting a void function
if(Pim.pifj.byte & 0x01) { //switch2 is pressed
potval = 1;
Pim.pifj.byte |= 0x01; //clear interrupt bit
//return potval; //doing this says the result is returned in void-result-function
}
else if(Pim.pifj.byte & 0x02) { //switch 3 is pressed
potval = 2;
Pim.pifj.byte |= 0x02; //clear interrupt bit
//return potval;
}
//return potval;
}
Here's the main.c.
int potval;
unsigned int i;
void main ()
{
adt(potval); //Warning: Result of function call is ignored
for (;;); //recurring loop until interrupt initiated
}
int adt(int potval, unsigned int i) {
if(potval == 1){
//for (;;){
while(potval==1){ //breaks when potval =2
i= Atd0.atddr[0].d10; //ATD bits
light7segment(i); // ATD changes number on 7segment display
m_delay(50);
}
}
else if (potval == 2){
light7segment(10); //ATD turns off 7segment display
}
}
Codewarrior gives this warning when you call a function with a return value but ignore checking that return value. As you do here:
adt(potval);
Normally the solution would be (void) adt(potval);.
Not in this case though, because the reason is a much more severe bug, namely that the function int adt(int potval, unsigned int i) doesn't return a value. On most Codewarrior target systems, it means that the caller code will grab some random value out of an accumulator, then run off into the woods. This bug could have be avoided if you had paid attention when the compiler said "return expected" in a different warning.
I am writing this program to write byte of data to each memeory location and then read and compare the stored bytes. However, when i am writing the data through FOR loop, the loop ends after 749 Writes and reset the Micro. i am resetting the WDT so that shouldnt be an issue. its a fairly simple programme and I was expecting it to work smoothly. here is the code:
I am using PIC24FJ256GB210 with 24LC512K serial EEPROM.
void memorytest2 (void)
{
unsigned int number;
unsigned int data =100;
ResetCOP();
if (loop == 1)
{
for (number=500; number < 1500; number++)
{
ResetCOP();
WriteEEByte(0xAA, EEPROMStart+data);
}
ResetCOP();
data++;
}
loop =0;
data =0;
number =500;
}
void WriteEEByte (unsigned char source,unsigned int dest)
{
I2C2CONbits.RCEN = 0; // disable rx MODE AS MASTER
StartWrite(dest); // start write process at address y
I2C2TRN = source; // put data in buffer
while (I2C2STATbits.TRSTAT);// wait for transmit to complete - including ack
I2C2CONbits.PEN = 1; // send stop condition to terminate write
while (I2C2CONbits.PEN);
ReadBusy(); //write delay (~5mS)
}
void ResetCOP (void)
{
asm("clrwdt");
}
I've written this code by looking at various examples: Python pulseaudio monitor, Pavumeter source, async playback example, and Pacat source.
I have successfully connected to a sink and am able to record it, but my problem is, I'm stuck at getting the volume value out. If I try printing value from the read function, I just get a bunch of random numbers at a second's interval.
Now I'm not asking for someone to finish writing the code for me, I'd just like some tips, help so that I could head towards the right direction. How do I retrieve the volume value?
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <pulse/pulseaudio.h>
static int latency = 20000; // start latency in micro seconds
static int sampleoffs = 0;
static short sampledata[300000];
static pa_buffer_attr bufattr;
static int underflows = 0;
static pa_sample_spec ss;
// This callback gets called when our context changes state. We really only
// care about when it's ready or if it has failed
void pa_state_cb(pa_context *c, void *userdata) {
pa_context_state_t state;
int *pa_ready = userdata;
state = pa_context_get_state(c);
switch (state) {
// These are just here for reference
case PA_CONTEXT_UNCONNECTED:
case PA_CONTEXT_CONNECTING:
case PA_CONTEXT_AUTHORIZING:
case PA_CONTEXT_SETTING_NAME:
default:
break;
case PA_CONTEXT_FAILED:
case PA_CONTEXT_TERMINATED:
*pa_ready = 2;
break;
case PA_CONTEXT_READY:
*pa_ready = 1;
break;
}
}
static void stream_read_cb(pa_stream *s, size_t length, void *userdata) {
const void *data;
pa_stream_peek(s, &data, &length);
data = (const unsigned char*) data;
printf("%u", data);
pa_stream_drop(s);
}
int main(int argc, char *argv[]) {
pa_mainloop *pa_ml;
pa_mainloop_api *pa_mlapi;
pa_context *pa_ctx;
pa_stream *recordstream;
int r;
int pa_ready = 0;
int retval = 0;
unsigned int a;
double amp;
int test = 0;
// Create a mainloop API and connection to the default server
pa_ml = pa_mainloop_new();
pa_mlapi = pa_mainloop_get_api(pa_ml);
pa_ctx = pa_context_new(pa_mlapi, "Simple PA test application");
pa_context_connect(pa_ctx, NULL, 0, NULL);
// This function defines a callback so the server will tell us it's state.
// Our callback will wait for the state to be ready. The callback will
// modify the variable to 1 so we know when we have a connection and it's
// ready.
// If there's an error, the callback will set pa_ready to 2
pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
// We can't do anything until PA is ready, so just iterate the mainloop
// and continue
while (pa_ready == 0) {
pa_mainloop_iterate(pa_ml, 1, NULL);
}
if (pa_ready == 2) {
retval = -1;
goto exit;
}
ss.rate = 44100;
ss.channels = 2;
ss.format = PA_SAMPLE_U8;
recordstream = pa_stream_new(pa_ctx, "Record", &ss, NULL);
if (!recordstream) {
printf("pa_stream_new failed\n");
}
pa_stream_set_read_callback(recordstream, stream_read_cb, NULL);
r = pa_stream_connect_record(recordstream, NULL, NULL, PA_STREAM_PEAK_DETECT);
if (r < 0) {
printf("pa_stream_connect_playback failed\n");
retval = -1;
goto exit;
}
// Run the mainloop until pa_mainloop_quit() is called
// (this example never calls it, so the mainloop runs forever).
// printf("%s", "Running Loop");
pa_mainloop_run(pa_ml, NULL);
exit:
// clean up and disconnect
pa_context_disconnect(pa_ctx);
pa_context_unref(pa_ctx);
pa_mainloop_free(pa_ml);
return retval;
}
Looking at the original question from UNIX.StackExchange, it looks like you're trying to create a VU meter. It can be done using an envelope detector. You have to read the input values and then average their rectified value. A simple envelope detector can be done as an exponential moving average filter.
float level = 0; // Init time
const float alpha = COEFFICIENT; // See below
...
// Inside sample loop
float input_signal = fabsf(get_current_sample());
level = level + alpha * (input_signal - level);
Here, alpha is the filter coefficient, which can be calculated as:
const float alpha = 1.0 - expf( (-2.0 * M_PI) / (TC * SAMPLE_RATE) );
Where TC is known as the "time constant" parameter, measured in seconds, which defines how fast you want to "follow" the signal. Setting it too short makes the VU meter very "bumpy" and setting it too long will miss transients in the signal. 10 mS is a good value to start from.
I get an error while trying to run the following code:
int SizeOfReadArray = 10;
int PacketLength = 5;
unsigned char rmessage[SizeOfReadArray];
unsigned long flag = 0;
unsigned char DataPacket[PacketLength];
int alternate = 1;
int remaining;
int Index;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
PacketExtraction();
}
void PacketExtraction(){
// Read Serial Buffer store in array
Serial.readBytes(rmessage,SizeOfReadArray);
// onetime execution for getting exact message from serial buffer
if (flag == 0){
for (int j=0;j<SizeOfReadArray;j++){
// check for start of packets through header bytes
if (rmessage[j+0] == 65 && rmessage[j+1] == 65){
// store the Index for extracting packet from message array
Index = j;
remaining = SizeOfReadArray-Index+PacketLength;
flag = 1;
}
}
}
// actual packet extraction
/* take PacketLength of data from serial burffr and store the rest
for remaining bytes for next data packet construction */
if (alternate == 1){
for (int k=0;k<5;k++){
DataPacket[k]=rmessage[k+Index];
}
// storing remaining bytes form next execution
unsigned char previouspacket[remaining];
for (int k=0;k<remaining;k++){
previouspacket[k] = rmessage[k+Index+PacketLength];
}
alternate = 0;
}
/* now this time take the previously saved remaining bytes of packet
and merge them with the current packet data */
else{
for (int k=0;k<remaining;k++){
DataPacket[k] = previouspacket[k];
}
for (int k=0;k<(remaining+1);k++){
DataPacket[k+remaining] = rmessage[k];
}
alternate = 1;
}
}
Error Message:
Arduino: 1.6.1 (Windows 7), Board: "Arduino Mega or Mega 2560,
ATmega2560 (Mega 2560)"
sketch_apr04b.ino: In function 'void PacketExtraction()':
sketch_apr04b.ino:52:23: error: 'previouspacket' was not declared in
this scope
Error compiling.
This report would have more information with "Show verbose output
during compilation" enabled in File > Preferences.
previouspacket is only declared in the first branch of the if…then blocks.
You should move unsigned char previouspacket[remaining]; before the if statement
I am trying to implement a simple audio delay in C.
i previously made a test delay program which operated on a printed sinewave and worked effectively.
I tried incorporating my delay as the process in the SFProcess - libsndfile- replacing the sinewave inputs with my audio 'data' input.
I nearly have it but instead of a clean sample delay I am getting all sorts of glitching and distortion.
Any ideas on how to correct this?
#include <stdio.h>
#include </usr/local/include/sndfile.h>//libsamplerate libsamplerate
//#include </usr/local/include/samplerate.h>
#define BUFFER_LEN 1024 //defines buffer length
#define MAX_CHANNELS 2 //defines max channels
static void process_data (double *data, double*circular,int count, int numchannels, int circular_pointer );
enum {DT_PROGNAME,ARG_INFILE,ARG_OUTFILE,ARG_NARGS, DT_VOL};
int main (int argc, const char * argv[])//Main
{
static double data [BUFFER_LEN]; // the buffer that carries the samples
double circular [44100] = {0}; // the circular buffer for the delay
for (int i = 0; i < 44100; i++) { circular[i] = 0; } // zero the circular buffer
int circular_pointer = 0; // where we currently are in the circular buffer
//float myvolume; // the volume entered by the user as optional 3rd argument
SNDFILE *infile, *outfile;
SF_INFO sfinfo;
int readcount;
const char *infilename = NULL;
const char *outfilename = NULL;
if(argc < ARG_NARGS) {
printf("usage: %s infile outfile\n",argv[DT_PROGNAME]);
return 1;
}
//if(argc > ARG_NARGS) {
//
// myvolume = argv[DT_VOL];
//};
infilename = argv[ARG_INFILE];
outfilename = argv[ARG_OUTFILE];
if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
{printf ("Not able to open input file %s.\n", infilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
};
if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)))
{ printf ("Not able to open output file %s.\n", outfilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
} ;
while ((readcount = sf_read_double (infile, data, BUFFER_LEN)))
{ process_data (data, circular, readcount, sfinfo.channels, circular_pointer) ;
sf_write_double (outfile, data, readcount) ;
};
sf_close (infile) ;
sf_close (outfile) ;
printf("the sample rate is %d\n", sfinfo.samplerate);
return 0;
}
static void process_data (double *data, double *circular, int count, int numchannels, int circular_pointer) {
//int j,k;
//float vol = 1;
int playhead;
int wraparound = 10000;
float delay = 1000; // delay time in samples
for (int ind = 0; ind < BUFFER_LEN; ind++){
circular_pointer = fmod(ind,wraparound); // wrap around pointer
circular[circular_pointer] = data[ind];
playhead = fmod(ind-delay, wraparound); // read the delayed signal
data[ind] = circular[playhead]; // output delayed signal
circular[ind] = data[ind]; // write the incoming signal
};
//volume
/*for (j=0; j<numchannels; j++) {
for (k=0; k<count; k++){
data[k] = data[k]*-vol;*/
//}printf ("the volume is %f", vol);
return;
}
There are a few issues with your code that are causing you to access out of your array bounds and to not read\write your circular buffer in the way intended.
I would suggest reading http://en.wikipedia.org/wiki/Circular_buffer to get a better understanding of circular buffers.
The main issues your code is suffering:
circular_pointer should be initialised to the delay amount (essentially the write head is starting at 0 so there is never any delay!)
playhead and circular_buffer are not updated between calls to process_data (circular_buffer is passed by value...)
playhead is reading from negative indices. The correct playhead calculation is
#define MAX_DELAY 44100
playhead++;
playhead = playhead%MAX_DELAY;
The second write to circular_buffer at the end of process_data is unnecessary and incorrect.
I would strongly suggest spending some time running your code in a debugger and closely watching what your playhead and circular_pointer are doing.
Mike
At least one problem is that you pass circular_pointer by value, not by reference. When you update it in the function, it's back to the same value next time you call the function.
I think you are on the right track, here, but if you want something that's structured a bit better, you might also want to checkout this answer:
how to add echo effect on audio file using objective-c
delay in sample can be put as 100 ms would be sufficient