From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: clemens@ladisch.de, tiwai@suse.de, perex@perex.cz
Cc: alsa-devel@alsa-project.org,
linux1394-devel@lists.sourceforge.net, ffado-devel@lists.sf.net
Subject: Sample program for hwdep interface
Date: Fri, 20 Dec 2013 23:46:15 +0900 [thread overview]
Message-ID: <52B45837.2080804@sakamocchi.jp> (raw)
In-Reply-To: <1387545269-3875-1-git-send-email-o-takashi@sakamocchi.jp>
This is how to use hwdep interface for firewire devices.
I hope FFADO developers read this.
With hwdep interface, the program in user land can do:
1.get firewire node infomation
2.get notification when starting/stopping kernel streaming
3.lock/unlock kernel streaming
For jackd with FFADO backend, it's better to lock kernel streaming in
advance. Then snd-bebob/snd-fireworks can't interrupt FFADO streaming.
And with snd-fireworks, the program can do:
4.transmit command of EFW transaction
5.receive response of EFW transaction
4/5 is my complete solution for ticket #360.
Make echo audiofire 8 and audiofire 12 work with recent firmwares
http://subversion.ffado.org/ticket/360
(I note 4 can be done via /dev/fw*. But I think 4 is easier.)
If someone works for snd-dice to support valid devices, it may be useful
that the program get dice notification in the same way.
(I have a little knowledgement about Dice.)
I attach sample program (too rough...) to show how to use hwdep interface.
Regards,
Takashi Sakamoto
====
/* monitor.c: program to monitor the status of firewire sound devices */
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <endian.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/epoll.h>
#include <souund/firewire.h>
static struct snd_firewire_get_info hwdep_info;
bool try_lock;
bool fireworks = false;
static void print_event_lock(struct snd_firewire_event_lock_status *msg,
int fd)
{
printf("\nLock Status:\n");
printf("Status:\t%s\n", msg->status ? "Locked" : "Unlocked" );
if (try_lock) {
if (ioctl(fd, SNDRV_FIREWIRE_IOCTL_LOCK) < 0)
printf("lock failed\n");
printf("lock success\n");
}
return;
}
static void print_event_dice(struct snd_firewire_event_dice_notification
*msg)
{
printf("\nDice Norification:\n");
printf("Notification: 0x%x\n", msg->notification);
return;
}
static void print_event_efw(struct snd_firewire_event_efw_response *evt,
int count)
{
uint32_t *resp;
struct snd_efw_transaction *t;
unsigned int i, index, length, params;
resp = evt->response;
count /= 4;
index = 0;
while (count > 0) {
t = (struct snd_efw_transaction *)resp;
length = be32toh(t->length);
printf("\nEFW Response %d:\n", index++);
printf("Length:\t\t%d\n", be32toh(t->length));
printf("Version:\t%d\n", be32toh(t->version));
printf("Seqnum:\t\t%d\n", be32toh(t->seqnum));
printf("Category:\t%d\n", be32toh(t->category));
printf("Command:\t%d\n", be32toh(t->command));
printf("Status:\t\t%d\n", be32toh(t->status));
params = length - sizeof(struct snd_efw_transaction) / sizeof(uint32_t);
if (params > 0)
for (i = 0; i < params; i++)
printf("params[%d]:\t%08X\n", i, be32toh(t->params[i]));
resp += length;
count -= length * sizeof(uint32_t);
}
}
static int read_event(int fd)
{
int count;
char buf[1024] = {0};
struct snd_firewire_event_common *event;
count = read(fd, buf, 1024);
if (count < 0)
return -1;
event = (struct snd_firewire_event_common *)buf;
if (event->type == SNDRV_FIREWIRE_EVENT_LOCK_STATUS)
print_event_lock((struct snd_firewire_event_lock_status *)buf, fd);
else if (event->type == SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION)
print_event_dice((struct snd_firewire_event_dice_notification *)buf);
else if (event->type == SNDRV_FIREWIRE_EVENT_EFW_RESPONSE)
print_event_efw((struct snd_firewire_event_efw_response *)buf, count);
return 0;
}
static int write_event(int fd)
{
int count;
struct snd_efw_transaction *t;
char buf[1024] = {0};
t = (struct snd_efw_transaction *)buf;
t->length = htobe32(6);
t->version = htobe32(1);
t->seqnum = htobe32(0);
t->category = htobe32(3);
t->command = htobe32(5);
t->status = htobe32(0);
count = write(fd, buf, sizeof(struct snd_efw_transaction));
if (count < 0)
printf("err: %d\n", count);
return count;
}
#define EVENTS 10
time_t cmd_deffer = 0;
static int main_loop(int fd)
{
int epfd, count, i, err;
time_t now;
struct epoll_event ev, events[EVENTS];
epfd = epoll_create(EVENTS);
if (epfd < 0) {
printf("error: %s\n", strerror(errno));
err = errno;
goto end;
}
memset(&ev, 0, sizeof(struct epoll_event));
ev.events = EPOLLIN;
ev.data.fd = fd;
if (fireworks)
ev.events |= EPOLLOUT;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
return errno;
while (1) {
count = epoll_wait(epfd, events, EVENTS, 200);
if (count == 0)
continue;
else if (count < 0) {
err = errno;
break;
}
for (i = 0; i < count; i++) {
if (events[i].events & EPOLLOUT) {
if (time(&now) < 0)
break;
if (now > cmd_deffer) {
if (write_event(events[i].data.fd) < 0) {
err = errno;
break;
}
cmd_deffer = now + 3;
}
}
if (events[i].events & EPOLLIN) {
if (read_event(events[i].data.fd) < 0) {
err = errno;
break;
}
}
}
}
end:
close(epfd);
return err;
}
int main(int argc, void *argv[])
{
int fd, count, err;
char buf[1024] = {};
struct snd_firewire_event_common *event;
if (argc > 2)
try_lock = true;
fd = open(argv[1], O_RDWR);
if (fd < 0) {
printf("fail to open: %s\n", (char *)argv[1]);
return 1;
}
if (ioctl(fd, SNDRV_FIREWIRE_IOCTL_GET_INFO, &hwdep_info) < 0) {
printf("error: %s\n", strerror(errno));
return 1;
}
printf("Information of Firewire Sound Device\n");
printf("type: %d\n", hwdep_info.type);
printf("card: %d\n", hwdep_info.card);
printf("GUID: 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
hwdep_info.guid[0], hwdep_info.guid[1], hwdep_info.guid[2],
hwdep_info.guid[3], hwdep_info.guid[4], hwdep_info.guid[5],
hwdep_info.guid[6], hwdep_info.guid[7] );
printf("Name: %s\n\n", hwdep_info.device_name);
if (hwdep_info.type == SNDRV_FIREWIRE_TYPE_FIREWORKS)
fireworks = true;
err = main_loop(fd);
close(fd);
return err;
}
next prev parent reply other threads:[~2013-12-20 14:46 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-20 13:13 [RFC v2][PATCH 00/38] Enhancement for support of some firewire devices Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 01/38] firewire-lib: Rename functions, structure, member for AMDTP Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 02/38] firewire-lib: Add macros instead of fixed value " Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 03/38] firewire-lib: Add 'direction' member to 'amdtp_stream' structure Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 04/38] firewire-lib: Split some codes into functions to reuse for both streams Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 05/38] firewire-lib: Add support for AMDTP in-stream and PCM capture Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 06/38] firewire-lib: Add support for MIDI capture/playback Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 07/38] firewire-lib: Give syt value as parameter to handle_out_packet() Takashi Sakamoto
2013-12-20 13:13 ` [PATCH 08/38] firewire-lib: Add support for duplex streams synchronization in blocking mode Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 09/38] firewire-lib: Add sort function for transmitted packet Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 10/38] firewire-lib: Add transfer delay to synchronized duplex streams Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 11/38] firewire-lib: Add support for channel mapping Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 12/38] firewire-lib: Rename macros, variables and functions for CMP Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 13/38] firewire-lib: Add 'direction' member to 'cmp_connection' structure Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 14/38] firewire-lib: Add handling output connection by CMP Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 15/38] firewire-lib: Add a new function to check others' connection Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 16/38] firewire-lib: Add some AV/C general commands Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 17/38] firewire-lib: Add quirks for Fireworks Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 18/38] fireworks: Add skelton for Fireworks based devices Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 19/38] fireworks: Add transaction and some commands Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 20/38] fireworks: Add connection and stream management Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 21/38] fireworks: Add proc interface for debugging purpose Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 22/38] fireworks: Add MIDI interface Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 23/38] fireworks: Add PCM interface Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 24/38] fireworks: Add hwdep interface Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 25/38] fireworks: Add command/response functionality into " Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 26/38] bebob: Add skelton for BeBoB based devices Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 27/38] bebob: Add commands and connections/streams management Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 28/38] bebob: Add proc interface for debugging purpose Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 29/38] bebob: Add MIDI interface Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 30/38] bebob: Add PCM interface Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 31/38] bebob: Add hwdep interface Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 32/38] bebob: Prepare for device specific operations Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 33/38] bebob: Add support for Terratec PHASE, EWS series and Aureon Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 34/38] bebob: Add support for Yamaha GO series Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 35/38] bebob: Add support for Focusrite Saffire/SaffirePro series Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 36/38] bebob: Add support for M-Audio usual Firewire series Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 37/38] bebob: Add support for M-Audio special " Takashi Sakamoto
2013-12-20 13:14 ` [PATCH 38/38] bebob: Send a cue to load firmware for M-Audio " Takashi Sakamoto
2013-12-20 14:46 ` Takashi Sakamoto [this message]
2013-12-21 10:11 ` [FFADO-devel] Sample program for hwdep interface Jonathan Woithe
2013-12-21 13:48 ` Clemens Ladisch
2014-01-05 11:18 ` Takashi Sakamoto
2014-01-12 13:22 ` Stefan Richter
2014-01-12 15:26 ` Takashi Sakamoto
2014-02-02 13:58 ` Echo Fireworks control protocol (was Re: Sample program for hwdep interface) Stefan Richter
2014-02-08 13:22 ` Takashi Sakamoto
2014-02-09 11:42 ` Jonathan Woithe
2014-02-09 14:51 ` Stefan Richter
2014-02-09 16:53 ` Takashi Sakamoto
2014-02-09 22:29 ` Jonathan Woithe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52B45837.2080804@sakamocchi.jp \
--to=o-takashi@sakamocchi.jp \
--cc=alsa-devel@alsa-project.org \
--cc=clemens@ladisch.de \
--cc=ffado-devel@lists.sf.net \
--cc=linux1394-devel@lists.sourceforge.net \
--cc=perex@perex.cz \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox