Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Gilbux (free)" <gilbux@free.fr>
To: alsa-devel@alsa-project.org
Subject: Dev: Alsa sequencer problem (Why ???)
Date: Mon, 01 Sep 2008 11:02:49 +0200	[thread overview]
Message-ID: <48BBAFB9.9080101@free.fr> (raw)

[-- Attachment #1: Type: text/plain, Size: 472 bytes --]

Hello,

I am trying to write an alsa sequencer. So I read as I can some of your 
tutorials, and I don't really understand what I am doing wrong, please 
help me.

I want to send scheduled event with the queuing system, but with RTC 
timer the queue doesn't start, and with the other timer the queue start 
but no events are sent.

I have joined to this email a small code, with the same kind of 
functions I am using, and some /proc/asound/seq/* outputs.

Regards,
Gilbux

[-- Attachment #2: TestQSchedEv.c --]
[-- Type: text/x-csrc, Size: 4548 bytes --]

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#include <alsa/asoundlib.h>

#define __TQSE_SEQNAME		"TestQSchedEv"
#define __TQSE_PORTNAME		"OutputPort"
#define __TQSE_QUEUENAME	"TQSE_Queue"

#define __TQSE_BPM		120
#define __TQSE_PPQ		192

#define __TQSE_ERR_CODE		-3

snd_seq_t		*seqh;
int			seqid, portid, queueid;

void			SetTempo(unsigned int bpm,
				 unsigned int ppq)
{
  snd_seq_queue_tempo_t	*tempo;
  unsigned int		beat_in_microsec
    = (unsigned int) (60000000 / bpm);
  int			err;

  snd_seq_queue_tempo_alloca(&tempo);
  snd_seq_queue_tempo_set_tempo(tempo, beat_in_microsec);
  snd_seq_queue_tempo_set_ppq(tempo, ppq);
  err = snd_seq_set_queue_tempo(seqh, queueid, tempo);
  if (err < 0)
    {
      fprintf(stderr,
	      "SetTempo: snd_seq_set_queue_tempo: %s\n",
	      snd_strerror(err));
      exit(__TQSE_ERR_CODE);
    }
  return;
}

void			StartQueue(void)
{
  int			err;

  snd_seq_start_queue(seqh, queueid, 0);
  err = snd_seq_drain_output(seqh);
  if (err < 0)
    {
      fprintf(stderr,
	      "StartQueue: snd_seq_drain_output: %s\n",
	      snd_strerror(err));
      exit(__TQSE_ERR_CODE);
    }
  return;
}

void			StopQueue(void)
{
  int			err;

  snd_seq_stop_queue(seqh, queueid, 0);
  err = snd_seq_drain_output(seqh);
  if (err < 0)
    {
      fprintf(stderr,
	      "StopQueue: snd_seq_drain_output: %s\n",
	      snd_strerror(err));
      exit(__TQSE_ERR_CODE);
    }
  return;
}

void			SetNoteEv(unsigned char channel,
				  unsigned char note,
				  unsigned int duration,
				  unsigned int ticktime)
{
  /* Trying to set queued note ev scheduled with ticktime. */
  snd_seq_event_t	ev;
  int			err;

  snd_seq_ev_clear(&ev);
  snd_seq_ev_schedule_tick(&ev, queueid, 0, ticktime);
  snd_seq_ev_set_source(&ev, portid);
  snd_seq_ev_set_subs(&ev);
  snd_seq_ev_set_note(&ev, channel, note, 127, duration);
  err = snd_seq_event_output_direct(seqh, &ev);
  if (err < 0)
    {
      fprintf(stderr,
	      "SetNoteEv: snd_seq_event_output_direct: %s\n",
	      snd_strerror(err));
      exit(__TQSE_ERR_CODE);
    }
  return;
}

void			InitSeqPortQueue(void)
{
  /* I try to init the alsa sequencer to just output
     event I don't touch the queue pool output, because
     it seems to have a default size in /proc/asound/seq/queue. */
  int			err;

  err = snd_seq_open(&seqh, "default", SND_SEQ_OPEN_OUTPUT, 0);
  if (err < 0)
    {
      fprintf(stderr, "snd_seq_open: %s\n", snd_strerror(err));
      exit(__TQSE_ERR_CODE);
    }
  err = snd_seq_set_client_name(seqh, __TQSE_SEQNAME);
  if (err < 0)
    {
      fprintf(stderr, "snd_seq_set_client_name: %s\n", snd_strerror(err));
      exit(__TQSE_ERR_CODE);
    }
  seqid = snd_seq_client_id(seqh);
  if (seqid < 0)
    {
      fprintf(stderr, "snd_seq_client_id: %s\n", snd_strerror(seqid));
      exit(__TQSE_ERR_CODE);
    }

  portid = snd_seq_create_simple_port(seqh, __TQSE_PORTNAME,
				      SND_SEQ_PORT_CAP_SUBS_READ	\
				      |SND_SEQ_PORT_CAP_READ, 0);
  if (portid < 0)
    {
      fprintf(stderr, "_Init_GAlsaSeqPort: snd_seq_create_simple_port: %s\n",
	      snd_strerror(portid));
      exit(__TQSE_ERR_CODE);
    }

  queueid = snd_seq_alloc_named_queue(seqh, __TQSE_QUEUENAME);
  if (queueid < 0)
    {
      fprintf(stderr, "_Init_GAlsaSeqQueue: snd_seq_alloc_named_queue: %s\n",
	      snd_strerror(queueid));
      exit(__TQSE_ERR_CODE);
    }
  return;
}

void			CloseSeqPortQueue(void)
{
  int			err;

  err = snd_seq_free_queue(seqh, queueid);
  if (err < 0)
    fprintf(stderr, "snd_seq_free_queue: %s\n", snd_strerror(err));
  err = snd_seq_delete_simple_port(seqh, portid);
  if (err < 0)
    fprintf(stderr, "close client port : %s\n", snd_strerror(err));
  err = snd_seq_close(seqh);
  if (err < 0)
    fprintf(stderr, "close seq client : %s\n", snd_strerror(err));
  return;
}

int			main(void)
{
  unsigned int		i;


  InitSeqPortQueue();
  SetTempo((unsigned int) __TQSE_BPM,
	   (unsigned int) __TQSE_PPQ);

  /* Preparing the queue to send an event every 4 beats */
  for (i = 0; i < 16; i++)
    SetNoteEv(1,
	      60,
	      (4 * __TQSE_PPQ),
	      (i * 16 * __TQSE_PPQ));

  printf("Press Enter to start the queue when all subscribtion are done.\n");
  /* trying to set enough time for event transimission */
  i = (17 * 60 / __TQSE_BPM) + 1;
  fgetc(stdin);
  printf("Starting the queue\n");
  StartQueue();
  sleep(i);
  printf("\nStopping the queue\n");
  StopQueue();

  CloseSeqPortQueue();
  return 0;
}

/* I compiled it with :
   gcc -Wall -g -o TestQSchedEv TestQSchedEv.c -lasound */

[-- Attachment #3: outputs.txt --]
[-- Type: text/plain, Size: 1609 bytes --]

/proc/asound/seq/* before starting the queue :
Client info
  cur  clients : 2
  peak clients : 3
  max  clients : 192

Client   0 : "System" [Kernel]
  Port   0 : "Timer" (Rwe-)
  Port   1 : "Announce" (R-e-)
Client 128 : "TestQSchedEv" [User]
  Port   0 : "OutputPort" (R-e-)
  Output pool :
    Pool size          : 500
    Cells in use       : 16
    Peak cells in use  : 16
    Alloc success      : 16
    Alloc failures     : 0
queue 0: [TQSE_Queue]
owned by client    : 128
lock status        : Locked
queued time events : 0
queued tick events : 16
timer state        : Stopped
timer PPQ          : 192
current tempo      : 500000
current BPM        : 120
current time       : 0.000000000 s
current tick       : 0

Timer for queue 0 : RTC timer
  Period time : 0.000000000
  Skew : 65536 / 65536

-----

/proc/asound/seq/* after starting the queue :
Client info
  cur  clients : 2
  peak clients : 3
  max  clients : 192

Client   0 : "System" [Kernel]
  Port   0 : "Timer" (Rwe-)
  Port   1 : "Announce" (R-e-)
Client 128 : "TestQSchedEv" [User]
  Port   0 : "OutputPort" (R-e-)
  Output pool :
    Pool size          : 500
    Cells in use       : 0
    Peak cells in use  : 16
    Alloc success      : 16
    Alloc failures     : 0
queue 0: [TQSE_Queue]
owned by client    : 128
lock status        : Locked
queued time events : 0
queued tick events : 0
timer state        : Running
timer PPQ          : 192
current tempo      : 500000
current BPM        : 120
current time       : 0.000000000 s
current tick       : 0

Timer for queue 0 : RTC timer
  Period time : 0.000976562
  Skew : 65536 / 65536

[-- Attachment #4: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

             reply	other threads:[~2008-09-01  9:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-01  9:02 Gilbux (free) [this message]
2008-09-15  9:32 ` Dev: Alsa sequencer problem (Why ???) gilbr

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=48BBAFB9.9080101@free.fr \
    --to=gilbux@free.fr \
    --cc=alsa-devel@alsa-project.org \
    /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