1
- /* $OpenBSD: dev.c,v 1.122 2025/06/16 06:19:29 ratchov Exp $ */
1
+ /* $OpenBSD: dev.c,v 1.123 2025/06/19 20:16:34 ratchov Exp $ */
2
2
/*
3
3
* Copyright (c) 2008-2012 Alexandre Ratchov <[email protected] >
4
4
*
@@ -78,7 +78,6 @@ unsigned int dev_sndnum = 0;
78
78
79
79
struct ctlslot ctlslot_array [DEV_NCTLSLOT ];
80
80
struct slot slot_array [DEV_NSLOT ];
81
- unsigned int slot_serial ; /* for slot allocation */
82
81
83
82
/*
84
83
* we support/need a single MTC clock source only
@@ -87,27 +86,6 @@ struct mtc mtc_array[1] = {
87
86
{.dev = NULL , .tstate = MTC_STOP }
88
87
};
89
88
90
- void
91
- slot_array_init (void )
92
- {
93
- unsigned int i ;
94
-
95
- for (i = 0 ; i < DEV_NSLOT ; i ++ ) {
96
- slot_array [i ].unit = i ;
97
- slot_array [i ].ops = NULL ;
98
- slot_array [i ].vol = MIDI_MAXCTL ;
99
- slot_array [i ].opt = NULL ;
100
- slot_array [i ].serial = slot_serial ++ ;
101
- memset (slot_array [i ].name , 0 , SLOT_NAMEMAX );
102
- }
103
- }
104
-
105
- void
106
- slot_ctlname (struct slot * s , char * name , size_t size )
107
- {
108
- snprintf (name , size , "slot%zu" , s - slot_array );
109
- }
110
-
111
89
void
112
90
zomb_onmove (void * arg )
113
91
{
@@ -298,16 +276,18 @@ mtc_midi_full(struct mtc *mtc)
298
276
299
277
/*
300
278
* send a volume change MIDI message
279
+ *
280
+ * XXX: rename to opt_midi_vol() and move to opt.c
301
281
*/
302
282
void
303
- dev_midi_vol (struct dev * d , struct slot * s )
283
+ dev_midi_vol (struct opt * o , struct app * a )
304
284
{
305
285
unsigned char msg [3 ];
306
286
307
- msg [0 ] = MIDI_CTL | (s - slot_array );
287
+ msg [0 ] = MIDI_CTL | (a - o -> app_array );
308
288
msg [1 ] = MIDI_CTL_VOL ;
309
- msg [2 ] = s -> vol ;
310
- dev_midi_send ( d , msg , 3 );
289
+ msg [2 ] = a -> vol ;
290
+ midi_send ( o -> midi , msg , sizeof ( msg ) );
311
291
}
312
292
313
293
/*
@@ -352,9 +332,11 @@ dev_midi_master(struct dev *d)
352
332
353
333
/*
354
334
* send a sndiod-specific slot description MIDI message
335
+ *
336
+ * XXX: rename to opt_midi_appdesc() and move to opt.c
355
337
*/
356
338
void
357
- dev_midi_slotdesc (struct dev * d , struct slot * s )
339
+ dev_midi_slotdesc (struct opt * o , struct app * a )
358
340
{
359
341
struct sysex x ;
360
342
@@ -364,34 +346,34 @@ dev_midi_slotdesc(struct dev *d, struct slot *s)
364
346
x .dev = SYSEX_DEV_ANY ;
365
347
x .id0 = SYSEX_AUCAT ;
366
348
x .id1 = SYSEX_AUCAT_SLOTDESC ;
367
- if (s -> opt != NULL && s -> opt -> dev == d )
368
- slot_ctlname (s , (char * )x .u .slotdesc .name , SYSEX_NAMELEN );
369
- x .u .slotdesc .chan = (s - slot_array );
349
+ strlcpy (x .u .slotdesc .name , a -> name , SYSEX_NAMELEN );
350
+ x .u .slotdesc .chan = (a - o -> app_array );
370
351
x .u .slotdesc .end = SYSEX_END ;
371
- dev_midi_send ( d , (unsigned char * )& x , SYSEX_SIZE (slotdesc ));
352
+ midi_send ( o -> midi , (unsigned char * )& x , SYSEX_SIZE (slotdesc ));
372
353
}
373
354
355
+ /*
356
+ * XXX: rename to opt_midi_dump() and move to opt.c
357
+ */
374
358
void
375
- dev_midi_dump (struct dev * d )
359
+ dev_midi_dump (struct opt * o )
376
360
{
377
361
struct sysex x ;
378
- struct slot * s ;
362
+ struct app * a ;
379
363
int i ;
380
364
381
- dev_midi_master (d );
382
- for (i = 0 , s = slot_array ; i < DEV_NSLOT ; i ++ , s ++ ) {
383
- if (s -> opt != NULL && s -> opt -> dev != d )
384
- continue ;
385
- dev_midi_slotdesc (d , s );
386
- dev_midi_vol (d , s );
365
+ dev_midi_master (o -> dev );
366
+ for (i = 0 , a = o -> app_array ; i < OPT_NAPP ; i ++ , a ++ ) {
367
+ dev_midi_slotdesc (o , a );
368
+ dev_midi_vol (o , a );
387
369
}
388
370
x .start = SYSEX_START ;
389
371
x .type = SYSEX_TYPE_EDU ;
390
372
x .dev = SYSEX_DEV_ANY ;
391
373
x .id0 = SYSEX_AUCAT ;
392
374
x .id1 = SYSEX_AUCAT_DUMPEND ;
393
375
x .u .dumpend .end = SYSEX_END ;
394
- dev_midi_send ( d , (unsigned char * )& x , SYSEX_SIZE (dumpend ));
376
+ midi_send ( o -> midi , (unsigned char * )& x , SYSEX_SIZE (dumpend ));
395
377
}
396
378
397
379
int
@@ -1523,98 +1505,30 @@ struct slot *
1523
1505
slot_new (struct opt * opt , unsigned int id , char * who ,
1524
1506
struct slotops * ops , void * arg , int mode )
1525
1507
{
1526
- char * p ;
1527
- char name [SLOT_NAMEMAX ];
1528
- char ctl_name [CTL_NAMEMAX ];
1529
- unsigned int i , ser , bestser , bestidx ;
1530
- struct slot * unit [DEV_NSLOT ];
1508
+ struct app * a ;
1531
1509
struct slot * s ;
1510
+ int i ;
1532
1511
1533
- /*
1534
- * create a ``valid'' control name (lowcase, remove [^a-z], truncate)
1535
- */
1536
- for (i = 0 , p = who ; ; p ++ ) {
1537
- if (i == SLOT_NAMEMAX - 1 || * p == '\0' ) {
1538
- name [i ] = '\0' ;
1539
- break ;
1540
- } else if (* p >= 'A' && * p <= 'Z' ) {
1541
- name [i ++ ] = * p + 'a' - 'A' ;
1542
- } else if (* p >= 'a' && * p <= 'z' )
1543
- name [i ++ ] = * p ;
1544
- }
1545
- if (i == 0 )
1546
- strlcpy (name , "noname" , SLOT_NAMEMAX );
1547
-
1548
- /*
1549
- * build a unit-to-slot map for this name
1550
- */
1551
- for (i = 0 ; i < DEV_NSLOT ; i ++ )
1552
- unit [i ] = NULL ;
1553
- for (i = 0 , s = slot_array ; i < DEV_NSLOT ; i ++ , s ++ ) {
1554
- if (strcmp (s -> name , name ) == 0 )
1555
- unit [s -> unit ] = s ;
1556
- }
1557
-
1558
- /*
1559
- * find the free slot with the least unit number and same id
1560
- */
1561
- for (i = 0 ; i < DEV_NSLOT ; i ++ ) {
1562
- s = unit [i ];
1563
- if (s != NULL && s -> ops == NULL && s -> id == id )
1564
- goto found ;
1565
- }
1566
-
1567
- /*
1568
- * find the free slot with the least unit number
1569
- */
1570
- for (i = 0 ; i < DEV_NSLOT ; i ++ ) {
1571
- s = unit [i ];
1572
- if (s != NULL && s -> ops == NULL ) {
1573
- s -> id = id ;
1574
- goto found ;
1575
- }
1576
- }
1512
+ a = opt_mkapp (opt , who );
1513
+ if (a == NULL )
1514
+ return NULL ;
1577
1515
1578
1516
/*
1579
- * couldn't find a matching slot, pick oldest free slot
1580
- * and set its name/unit
1517
+ * find a free slot and assign it the smallest possible unit number
1581
1518
*/
1582
- bestser = 0 ;
1583
- bestidx = DEV_NSLOT ;
1584
1519
for (i = 0 , s = slot_array ; i < DEV_NSLOT ; i ++ , s ++ ) {
1585
- if (s -> ops != NULL )
1586
- continue ;
1587
- ser = slot_serial - s -> serial ;
1588
- if (ser > bestser ) {
1589
- bestser = ser ;
1590
- bestidx = i ;
1591
- }
1520
+ if (s -> ops == NULL )
1521
+ break ;
1592
1522
}
1593
-
1594
- if (bestidx == DEV_NSLOT ) {
1595
- logx (1 , "%s: out of sub-device slots" , name );
1523
+ if (i == DEV_NSLOT ) {
1524
+ logx (1 , "%s: too many connections" , a -> name );
1596
1525
return NULL ;
1597
1526
}
1598
1527
1599
- s = slot_array + bestidx ;
1600
- ctl_del (CTL_SLOT_LEVEL , s , NULL );
1601
- s -> vol = MIDI_MAXCTL ;
1602
- strlcpy (s -> name , name , SLOT_NAMEMAX );
1603
- s -> serial = slot_serial ++ ;
1604
- for (i = 0 ; unit [i ] != NULL ; i ++ )
1605
- ; /* nothing */
1606
- s -> unit = i ;
1607
- s -> id = id ;
1608
- s -> opt = opt ;
1609
- slot_ctlname (s , ctl_name , CTL_NAMEMAX );
1610
- ctl_new (CTL_SLOT_LEVEL , s , NULL ,
1611
- CTL_NUM , "" , "app" , ctl_name , -1 , "level" ,
1612
- NULL , -1 , 127 , s -> vol );
1613
-
1614
- found :
1615
- /* open device, this may change opt's device */
1616
1528
if (!opt_ref (opt ))
1617
1529
return NULL ;
1530
+
1531
+ s -> app = a ;
1618
1532
s -> opt = opt ;
1619
1533
s -> ops = ops ;
1620
1534
s -> arg = arg ;
@@ -1629,10 +1543,8 @@ slot_new(struct opt *opt, unsigned int id, char *who,
1629
1543
s -> appbufsz = s -> opt -> dev -> bufsz ;
1630
1544
s -> round = s -> opt -> dev -> round ;
1631
1545
s -> rate = s -> opt -> dev -> rate ;
1632
- dev_midi_slotdesc (s -> opt -> dev , s );
1633
- dev_midi_vol (s -> opt -> dev , s );
1634
1546
#ifdef DEBUG
1635
- logx (3 , "slot%zu: %s/%s%u " , s - slot_array , s -> opt -> name , s -> name , s -> unit );
1547
+ logx (3 , "slot%zu: %s/%s" , s - slot_array , s -> opt -> name , s -> app -> name );
1636
1548
#endif
1637
1549
return s ;
1638
1550
}
@@ -1660,66 +1572,21 @@ slot_del(struct slot *s)
1660
1572
}
1661
1573
1662
1574
/*
1663
- * change the slot play volume; called either by the slot or by MIDI
1575
+ * change the slot play volume; called by the client
1664
1576
*/
1665
1577
void
1666
1578
slot_setvol (struct slot * s , unsigned int vol )
1667
1579
{
1580
+ struct opt * o = s -> opt ;
1581
+ struct app * a = s -> app ;
1582
+
1668
1583
#ifdef DEBUG
1669
1584
logx (3 , "slot%zu: setting volume %u" , s - slot_array , vol );
1670
1585
#endif
1671
- s -> vol = vol ;
1672
- s -> mix .vol = MIDI_TO_ADATA (s -> vol );
1673
- }
1674
-
1675
- /*
1676
- * set device for this slot
1677
- */
1678
- void
1679
- slot_setopt (struct slot * s , struct opt * o )
1680
- {
1681
- struct opt * t ;
1682
- struct dev * odev , * ndev ;
1683
- struct ctl * c ;
1684
-
1685
- if (s -> opt == NULL || s -> opt == o )
1686
- return ;
1687
-
1688
- logx (2 , "slot%zu: moving to opt %s" , s - slot_array , o -> name );
1689
-
1690
- odev = s -> opt -> dev ;
1691
- if (s -> ops != NULL ) {
1692
- ndev = opt_ref (o );
1693
- if (ndev == NULL )
1694
- return ;
1695
-
1696
- if (!dev_iscompat (odev , ndev )) {
1697
- opt_unref (o );
1698
- return ;
1699
- }
1700
- }
1701
-
1702
- if (s -> pstate == SLOT_RUN || s -> pstate == SLOT_STOP )
1703
- slot_detach (s );
1704
-
1705
- t = s -> opt ;
1706
- s -> opt = o ;
1707
-
1708
- c = ctl_find (CTL_SLOT_LEVEL , s , NULL );
1709
- ctl_update (c );
1710
-
1711
- if (o -> dev != t -> dev ) {
1712
- dev_midi_slotdesc (odev , s );
1713
- dev_midi_slotdesc (ndev , s );
1714
- dev_midi_vol (ndev , s );
1715
- }
1716
-
1717
- if (s -> pstate == SLOT_RUN || s -> pstate == SLOT_STOP )
1718
- slot_attach (s );
1719
-
1720
- if (s -> ops != NULL ) {
1721
- opt_unref (t );
1722
- return ;
1586
+ if (a -> vol != vol ) {
1587
+ opt_appvol (o , a , vol );
1588
+ dev_midi_vol (o , a );
1589
+ ctl_onval (CTL_APP_LEVEL , o , a , vol );
1723
1590
}
1724
1591
}
1725
1592
@@ -1775,7 +1642,7 @@ slot_attach(struct slot *s)
1775
1642
s -> next = d -> slot_list ;
1776
1643
d -> slot_list = s ;
1777
1644
if (s -> mode & MODE_PLAY ) {
1778
- s -> mix .vol = MIDI_TO_ADATA (s -> vol );
1645
+ s -> mix .vol = MIDI_TO_ADATA (s -> app -> vol );
1779
1646
dev_mix_adjvol (d );
1780
1647
}
1781
1648
}
@@ -2073,8 +1940,8 @@ ctlslot_visible(struct ctlslot *s, struct ctl *c)
2073
1940
return (s -> opt -> dev == c -> u .any .arg0 );
2074
1941
case CTL_OPT_DEV :
2075
1942
return (s -> opt == c -> u .any .arg0 );
2076
- case CTL_SLOT_LEVEL :
2077
- return (s -> opt -> dev == c -> u .slot_level . slot -> opt -> dev );
1943
+ case CTL_APP_LEVEL :
1944
+ return (s -> opt == c -> u .app_level . opt );
2078
1945
default :
2079
1946
return 0 ;
2080
1947
}
@@ -2146,9 +2013,9 @@ ctl_scope_fmt(char *buf, size_t size, struct ctl *c)
2146
2013
case CTL_DEV_MASTER :
2147
2014
return snprintf (buf , size , "dev_master:%s" ,
2148
2015
c -> u .dev_master .dev -> name );
2149
- case CTL_SLOT_LEVEL :
2150
- return snprintf (buf , size , "slot_level :%s%u " ,
2151
- c -> u .slot_level . slot -> name , c -> u .slot_level . slot -> unit );
2016
+ case CTL_APP_LEVEL :
2017
+ return snprintf (buf , size , "app_level :%s/%s " ,
2018
+ c -> u .app_level . opt -> name , c -> u .app_level . app -> name );
2152
2019
case CTL_OPT_DEV :
2153
2020
return snprintf (buf , size , "opt_dev:%s/%s" ,
2154
2021
c -> u .opt_dev .opt -> name , c -> u .opt_dev .dev -> name );
@@ -2208,10 +2075,9 @@ ctl_setval(struct ctl *c, int val)
2208
2075
c -> val_mask = ~0U ;
2209
2076
c -> curval = val ;
2210
2077
return 1 ;
2211
- case CTL_SLOT_LEVEL :
2212
- slot_setvol (c -> u .slot_level .slot , val );
2213
- // XXX change dev_midi_vol() into slot_midi_vol()
2214
- dev_midi_vol (c -> u .slot_level .slot -> opt -> dev , c -> u .slot_level .slot );
2078
+ case CTL_APP_LEVEL :
2079
+ opt_appvol (c -> u .app_level .opt , c -> u .app_level .app , val );
2080
+ dev_midi_vol (c -> u .app_level .opt , c -> u .app_level .app );
2215
2081
c -> val_mask = ~0U ;
2216
2082
c -> curval = val ;
2217
2083
return 1 ;
@@ -2272,6 +2138,7 @@ ctl_new(int scope, void *arg0, void *arg1,
2272
2138
c -> u .hw .addr = * (unsigned int * )arg1 ;
2273
2139
break ;
2274
2140
case CTL_OPT_DEV :
2141
+ case CTL_APP_LEVEL :
2275
2142
c -> u .any .arg1 = arg1 ;
2276
2143
break ;
2277
2144
default :
@@ -2337,6 +2204,7 @@ ctl_match(struct ctl *c, int scope, void *arg0, void *arg1)
2337
2204
return 0 ;
2338
2205
break ;
2339
2206
case CTL_OPT_DEV :
2207
+ case CTL_APP_LEVEL :
2340
2208
if (arg1 != NULL && c -> u .any .arg1 != arg1 )
2341
2209
return 0 ;
2342
2210
break ;
0 commit comments