~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to audio/audio.c

  • Committer: Bazaar Package Importer
  • Author(s): Riku Voipio, Josh Triplett, Riku Voipio
  • Date: 2009-07-29 13:28:05 UTC
  • mfrom: (1.4.1 upstream)
  • mto: (12.1.1 sid) (10.1.13 sid)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20090729132805-cau7rfexh7dawyb8
Tags: 0.10.50+git20090729-1
[ Josh Triplett ]
* Remove myself from Uploaders.

[ Riku Voipio ]
* new upstream RC version
* nuke all linux-user patches (applied upstream)
  06_exit_segfault
  12_signal_powerpc_support
  21_net_soopts
  30_syscall_ipc
  32_syscall_sysctl
  35_syscall_sockaddr
  48_signal_terminate
  55_unmux_socketcall
* nuke all other applied-upstream patches
  01_nostrip (better version upstream)
  07_i386_exec_name (can be reintroduced in debian/rules)
  50_linuxbios_isa_bios_ram (shouldn't be needed anymore)
  51_linuxbios_piix_ram_size (applied)
  56_dhcp (crap)
  60_ppc_ld (reintroduce if needed)
  64_ppc_asm_constraints (ditto)
  66_tls_ld.patch (ditto)
  81_compile_dtb.patch (applied upstream)
  82_qemu-img_decimal (ditto)
* move to git
* simplify build rules
* Correct my email address

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 */
24
24
#include "hw/hw.h"
25
25
#include "audio.h"
26
 
#include "console.h"
 
26
#include "monitor.h"
27
27
#include "qemu-timer.h"
28
28
#include "sysemu.h"
29
29
 
37
37
 
38
38
#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
39
39
 
 
40
 
 
41
/* Order of CONFIG_AUDIO_DRIVERS is import.
 
42
   The 1st one is the one used by default, that is the reason
 
43
    that we generate the list.
 
44
*/
40
45
static struct audio_driver *drvtab[] = {
41
 
    AUDIO_DRIVERS
 
46
    CONFIG_AUDIO_DRIVERS
42
47
    &no_audio_driver,
43
48
    &wav_audio_driver
44
49
};
60
65
    int plive;
61
66
    int log_to_monitor;
62
67
} conf = {
63
 
    {                           /* DAC fixed settings */
64
 
        1,                      /* enabled */
65
 
        1,                      /* nb_voices */
66
 
        1,                      /* greedy */
67
 
        {
68
 
            44100,              /* freq */
69
 
            2,                  /* nchannels */
70
 
            AUD_FMT_S16,        /* fmt */
71
 
            AUDIO_HOST_ENDIANNESS
72
 
        }
73
 
    },
74
 
 
75
 
    {                           /* ADC fixed settings */
76
 
        1,                      /* enabled */
77
 
        1,                      /* nb_voices */
78
 
        1,                      /* greedy */
79
 
        {
80
 
            44100,              /* freq */
81
 
            2,                  /* nchannels */
82
 
            AUD_FMT_S16,        /* fmt */
83
 
            AUDIO_HOST_ENDIANNESS
84
 
        }
85
 
    },
86
 
 
87
 
    { 250 },                    /* period */
88
 
    0,                          /* plive */
89
 
    0                           /* log_to_monitor */
 
68
    .fixed_out = { /* DAC fixed settings */
 
69
        .enabled = 1,
 
70
        .nb_voices = 1,
 
71
        .greedy = 1,
 
72
        .settings = {
 
73
            .freq = 44100,
 
74
            .nchannels = 2,
 
75
            .fmt = AUD_FMT_S16,
 
76
            .endianness =  AUDIO_HOST_ENDIANNESS,
 
77
        }
 
78
    },
 
79
 
 
80
    .fixed_in = { /* ADC fixed settings */
 
81
        .enabled = 1,
 
82
        .nb_voices = 1,
 
83
        .greedy = 1,
 
84
        .settings = {
 
85
            .freq = 44100,
 
86
            .nchannels = 2,
 
87
            .fmt = AUD_FMT_S16,
 
88
            .endianness = AUDIO_HOST_ENDIANNESS,
 
89
        }
 
90
    },
 
91
 
 
92
    .period = { .hertz = 250 },
 
93
    .plive = 0,
 
94
    .log_to_monitor = 0,
90
95
};
91
96
 
92
97
static AudioState glob_audio_state;
93
98
 
94
99
struct mixeng_volume nominal_volume = {
95
 
    0,
 
100
    .mute = 0,
96
101
#ifdef FLOAT_MIXENG
97
 
    1.0,
98
 
    1.0
 
102
    .r = 1.0,
 
103
    .l = 1.0,
99
104
#else
100
 
    1ULL << 32,
101
 
    1ULL << 32
 
105
    .r = 1ULL << 32,
 
106
    .l = 1ULL << 32,
102
107
#endif
103
108
};
104
109
 
328
333
{
329
334
    if (conf.log_to_monitor) {
330
335
        if (cap) {
331
 
            term_printf ("%s: ", cap);
 
336
            monitor_printf(cur_mon, "%s: ", cap);
332
337
        }
333
338
 
334
 
        term_vprintf (fmt, ap);
 
339
        monitor_vprintf(cur_mon, fmt, ap);
335
340
    }
336
341
    else {
337
342
        if (cap) {
707
712
}
708
713
 
709
714
static CaptureVoiceOut *audio_pcm_capture_find_specific (
710
 
    AudioState *s,
711
715
    struct audsettings *as
712
716
    )
713
717
{
714
718
    CaptureVoiceOut *cap;
 
719
    AudioState *s = &glob_audio_state;
715
720
 
716
721
    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
717
722
        if (audio_pcm_info_eq (&cap->hw.info, as)) {
786
791
    }
787
792
}
788
793
 
789
 
static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
 
794
static int audio_attach_capture (HWVoiceOut *hw)
790
795
{
 
796
    AudioState *s = &glob_audio_state;
791
797
    CaptureVoiceOut *cap;
792
798
 
793
799
    audio_detach_capture (hw);
1295
1301
    HWVoiceOut *hw = NULL;
1296
1302
    SWVoiceOut *sw;
1297
1303
 
1298
 
    while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
 
1304
    while ((hw = audio_pcm_hw_find_any_enabled_out (hw))) {
1299
1305
        int played;
1300
1306
        int live, free, nb_live, cleanup_required, prev_rpos;
1301
1307
 
1390
1396
#ifdef DEBUG_PLIVE
1391
1397
                    dolog ("Finishing with old voice\n");
1392
1398
#endif
1393
 
                    audio_close_out (s, sw);
 
1399
                    audio_close_out (sw);
1394
1400
                }
1395
1401
                sw = sw1;
1396
1402
            }
1402
1408
{
1403
1409
    HWVoiceIn *hw = NULL;
1404
1410
 
1405
 
    while ((hw = audio_pcm_hw_find_any_enabled_in (s, hw))) {
 
1411
    while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) {
1406
1412
        SWVoiceIn *sw;
1407
1413
        int captured, min;
1408
1414
 
1610
1616
    s->drv_opaque = drv->init ();
1611
1617
 
1612
1618
    if (s->drv_opaque) {
1613
 
        audio_init_nb_voices_out (s, drv);
1614
 
        audio_init_nb_voices_in (s, drv);
 
1619
        audio_init_nb_voices_out (drv);
 
1620
        audio_init_nb_voices_in (drv);
1615
1621
        s->drv = drv;
1616
1622
        return 0;
1617
1623
    }
1630
1636
    int op = running ? VOICE_ENABLE : VOICE_DISABLE;
1631
1637
 
1632
1638
    s->vm_running = running;
1633
 
    while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
 
1639
    while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1634
1640
        hwo->pcm_ops->ctl_out (hwo, op);
1635
1641
    }
1636
1642
 
1637
 
    while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
 
1643
    while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1638
1644
        hwi->pcm_ops->ctl_in (hwi, op);
1639
1645
    }
1640
1646
}
1645
1651
    HWVoiceOut *hwo = NULL;
1646
1652
    HWVoiceIn *hwi = NULL;
1647
1653
 
1648
 
    while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
 
1654
    while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
1649
1655
        SWVoiceCap *sc;
1650
1656
 
1651
1657
        hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
1661
1667
        }
1662
1668
    }
1663
1669
 
1664
 
    while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
 
1670
    while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
1665
1671
        hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
1666
1672
        hwi->pcm_ops->fini_in (hwi);
1667
1673
    }
1689
1695
    return 0;
1690
1696
}
1691
1697
 
1692
 
void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card)
1693
 
{
1694
 
    card->audio = s;
1695
 
    card->name = qemu_strdup (name);
1696
 
    memset (&card->entries, 0, sizeof (card->entries));
1697
 
    LIST_INSERT_HEAD (&s->card_head, card, entries);
1698
 
}
1699
 
 
1700
 
void AUD_remove_card (QEMUSoundCard *card)
1701
 
{
1702
 
    LIST_REMOVE (card, entries);
1703
 
    card->audio = NULL;
1704
 
    qemu_free (card->name);
1705
 
}
1706
 
 
1707
 
AudioState *AUD_init (void)
 
1698
static void audio_init (void)
1708
1699
{
1709
1700
    size_t i;
1710
1701
    int done = 0;
1711
1702
    const char *drvname;
1712
1703
    AudioState *s = &glob_audio_state;
1713
1704
 
 
1705
    if (s->drv) {
 
1706
        return;
 
1707
    }
 
1708
 
1714
1709
    LIST_INIT (&s->hw_head_out);
1715
1710
    LIST_INIT (&s->hw_head_in);
1716
1711
    LIST_INIT (&s->cap_head);
1718
1713
 
1719
1714
    s->ts = qemu_new_timer (vm_clock, audio_timer, s);
1720
1715
    if (!s->ts) {
1721
 
        dolog ("Could not create audio timer\n");
1722
 
        return NULL;
 
1716
        hw_error("Could not create audio timer\n");
1723
1717
    }
1724
1718
 
1725
1719
    audio_process_options ("AUDIO", audio_options);
1772
1766
    if (!done) {
1773
1767
        done = !audio_driver_init (s, &no_audio_driver);
1774
1768
        if (!done) {
1775
 
            dolog ("Could not initialize audio subsystem\n");
 
1769
            hw_error("Could not initialize audio subsystem\n");
1776
1770
        }
1777
1771
        else {
1778
1772
            dolog ("warning: Using timer based audio emulation\n");
1779
1773
        }
1780
1774
    }
1781
1775
 
1782
 
    if (done) {
1783
 
        VMChangeStateEntry *e;
1784
 
 
1785
 
        if (conf.period.hertz <= 0) {
1786
 
            if (conf.period.hertz < 0) {
1787
 
                dolog ("warning: Timer period is negative - %d "
1788
 
                       "treating as zero\n",
1789
 
                       conf.period.hertz);
1790
 
            }
1791
 
            conf.period.ticks = 1;
1792
 
        }
1793
 
        else {
1794
 
            conf.period.ticks = ticks_per_sec / conf.period.hertz;
1795
 
        }
1796
 
 
1797
 
        e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
1798
 
        if (!e) {
1799
 
            dolog ("warning: Could not register change state handler\n"
1800
 
                   "(Audio can continue looping even after stopping the VM)\n");
1801
 
        }
 
1776
    VMChangeStateEntry *e;
 
1777
 
 
1778
    if (conf.period.hertz <= 0) {
 
1779
        if (conf.period.hertz < 0) {
 
1780
            dolog ("warning: Timer period is negative - %d "
 
1781
                   "treating as zero\n",
 
1782
                   conf.period.hertz);
 
1783
        }
 
1784
        conf.period.ticks = 1;
 
1785
    } else {
 
1786
        conf.period.ticks = ticks_per_sec / conf.period.hertz;
1802
1787
    }
1803
 
    else {
1804
 
        qemu_del_timer (s->ts);
1805
 
        return NULL;
 
1788
 
 
1789
    e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
 
1790
    if (!e) {
 
1791
        dolog ("warning: Could not register change state handler\n"
 
1792
               "(Audio can continue looping even after stopping the VM)\n");
1806
1793
    }
1807
1794
 
1808
1795
    LIST_INIT (&s->card_head);
1809
1796
    register_savevm ("audio", 0, 1, audio_save, audio_load, s);
1810
1797
    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
1811
 
    return s;
1812
 
}
 
1798
}
 
1799
 
 
1800
void AUD_register_card (const char *name, QEMUSoundCard *card)
 
1801
{
 
1802
    audio_init ();
 
1803
    card->name = qemu_strdup (name);
 
1804
    memset (&card->entries, 0, sizeof (card->entries));
 
1805
    LIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries);
 
1806
}
 
1807
 
 
1808
void AUD_remove_card (QEMUSoundCard *card)
 
1809
{
 
1810
    LIST_REMOVE (card, entries);
 
1811
    qemu_free (card->name);
 
1812
}
 
1813
 
1813
1814
 
1814
1815
CaptureVoiceOut *AUD_add_capture (
1815
 
    AudioState *s,
1816
1816
    struct audsettings *as,
1817
1817
    struct audio_capture_ops *ops,
1818
1818
    void *cb_opaque
1819
1819
    )
1820
1820
{
 
1821
    AudioState *s = &glob_audio_state;
1821
1822
    CaptureVoiceOut *cap;
1822
1823
    struct capture_callback *cb;
1823
1824
 
1824
 
    if (!s) {
1825
 
        /* XXX suppress */
1826
 
        s = &glob_audio_state;
1827
 
    }
1828
 
 
1829
1825
    if (audio_validate_settings (as)) {
1830
1826
        dolog ("Invalid settings were passed when trying to add capture\n");
1831
1827
        audio_print_settings (as);
1841
1837
    cb->ops = *ops;
1842
1838
    cb->opaque = cb_opaque;
1843
1839
 
1844
 
    cap = audio_pcm_capture_find_specific (s, as);
 
1840
    cap = audio_pcm_capture_find_specific (as);
1845
1841
    if (cap) {
1846
1842
        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
1847
1843
        return cap;
1891
1887
        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
1892
1888
 
1893
1889
        hw = NULL;
1894
 
        while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
1895
 
            audio_attach_capture (s, hw);
 
1890
        while ((hw = audio_pcm_hw_find_any_out (hw))) {
 
1891
            audio_attach_capture (hw);
1896
1892
        }
1897
1893
        return cap;
1898
1894