All of lore.kernel.org
 help / color / mirror / Atom feed
* Dev: Alsa sequencer problem (Why ???)
@ 2008-09-01  9:02 Gilbux (free)
  2008-09-15  9:32 ` gilbr
  0 siblings, 1 reply; 2+ messages in thread
From: Gilbux (free) @ 2008-09-01  9:02 UTC (permalink / raw)
  To: alsa-devel

[-- 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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-09-15 17:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-01  9:02 Dev: Alsa sequencer problem (Why ???) Gilbux (free)
2008-09-15  9:32 ` gilbr

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.