The implementation is simple: I use a timer that triggers every seconds. In the meanwhile I count the incoming samples. On a triggered timer event, I output the counted samples and reset the counter.
Here is my code:
Code: Select all
#include <xs1.h>
#include <stdio.h>
#include <platform.h>
#include "spdif.h"
on stdcore[1] : port spdif_rx_port = XS1_PORT_1O;
on stdcore[1] : clock clock_block = XS1_CLKBLK_1;
interface event {
void triggered();
};
#define FRAME_Y 5
void spdif_rx_handler(streaming chanend c, client interface event event_intf) {
delay_microseconds(1000);
while (1) {
select {
case c :> uint32_t v:
uint32_t index = (v & 0xF) == FRAME_Y ? 1 : 0;
uint32_t sample = (v & ~0xF) << 4;
// TODO interpret none sample bits
if (index) event_intf.triggered(); // count only the samples of the right channel
break;
}
}
}
void timed_event_producer(client interface event event_intf) {
timer t;
unsigned int time;
t :> time;
while (1) {
select {
case t when timerafter(time) :> void:
time += XS1_TIMER_MHZ * 1000 * 1000; // should be 1 second
event_intf.triggered();
break;
}
}
}
void sample_rate_calculator(server interface event sample_event_intf, server interface event timed_event_intf) {
int count_samples = 0;
while (1) {
select {
case sample_event_intf.triggered():
count_samples++;
break;
case timed_event_intf.triggered():
printf("Detected sample rate: %u\n", count_samples);
count_samples = 0;
break;
}
}
}
int main(void) {
streaming chan spdif_rx_channel;
interface event timed_event_intf, sample_event_intf;
par {
on stdcore[1]: sample_rate_calculator(sample_event_intf, timed_event_intf);
on stdcore[1]: timed_event_producer(timed_event_intf);
on stdcore[1]: spdif_rx_handler(spdif_rx_channel, sample_event_intf);
on stdcore[1]: spdif_rx(spdif_rx_channel, spdif_rx_port, clock_block, 44100);
}
return 0;
}
Do you have some ideas to solve the rate calculating problem?