This file is indexed.

/usr/share/apport/symptoms/audio.py is in apport-symptoms 0.20.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# Sound/audio related problem troubleshooter/triager
# Written by David Henningsson 2010, david.henningsson@canonical.com
# Copyright Canonical Ltd 2010
# License: BSD (see /usr/share/common-licenses/BSD )

description = 'Sound/audio related problems'

import apport
from apport.hookutils import *
import re
import os
import sys
import subprocess

sys.path.append('/usr/share/apport/symptoms/')
from _audio_data import *
from _audio_checks import *

def ask_jack_and_card(report, ui):
    ''' Reports what jack and/or card the user has a problem with 
        Returns (package, card, isOutput, jack) tuple '''
    cards = parse_cards()
    jacks = []
    for c in cards:
       for j in c.jacks:
            jacks.append((c,j))
 
    # Ask for a specific jack   
    if len(jacks) > 0:
        choices = ["%s (%s)" % (j.pretty_name(), c.pretty_name()) 
            for c,j in jacks]
        choices.append("It's not listed here")
        nr = ui.choice('What hardware are you having a problem with?\n',
            choices)
        if nr is None:
            raise StopIteration
        nr = nr[0]
        if (nr < len(jacks)):
            c,j = jacks[nr]
            report['Symptom_Card'] = c.pretty_name()
            report['Symptom_Jack'] = j.pretty_name()
            return (None, c, j.isOutput(), j)

    # Okay, not a specific jack, let's ask for sound cards
    choices = []
    interfaces = ['PCI/internal', 'USB', 'Firewire', 'Bluetooth']
    for c in cards:
        choices.append("Playback from %s" % c.pretty_name())
        choices.append("Recording from %s" % c.pretty_name())
    choices.extend(["%s device not listed here" % i for i in interfaces])
    nr = ui.choice("What audio device are you having a problem with?",
        choices)
    if nr is None:
        raise StopIteration
    nr = nr[0]
    if int(nr / 2) < len(cards):
        report['Symptom_Card'] = c.pretty_name()
        return (None, cards[int(nr/2)], nr % 2 == 0, None)

    # card not detected by alsa, nor pulse
    nr = nr - 2 * len(cards)
    report['Title'] = "%s sound card not detected" % interfaces[nr]
    
    if interfaces[nr] == 'Firewire':
        if not ui.yesno('External firewire cards require manual setup.\n'
            'Documentation is here: https://help.ubuntu.com/community/HowToJACKConfiguration\n'
            'Would you like to continue reporting a bug anyway?'):
            raise StopIteration
        return ('libffado1', None, None, None)    
    
    return ('alsa-base', None, None, None)


def symptom_fails_after_a_while(report, ui, card, isOutput, jack):
    pa_start_logging()
    ui.information("Please try to reproduce the problem now. Close this dialog\n"
        "when the problem has appeared.")
    pa_finish_logging(report)
    report['Title'] = get_hw_title(card, isOutput, jack, "fails after a while")
    return 'alsa-base'

def symptom_distortion(report, ui, card, isOutput, jack):
    check_volumes(report, ui, card, isOutput, jack, 0)
    p = check_test_tones(report, ui, card, isOutput, jack)
    report['Title'] = get_hw_title(card, isOutput, jack, "Sound is distorted")
    return p

def symptom_background_noise(report, ui, card, isOutput, jack):
    check_volumes(report, ui, card, isOutput, jack)
    p = check_test_tones(report, ui, card, isOutput, jack)
    report['Title'] = get_hw_title(card, isOutput, jack, "Background noise or low volume")
    return p
    
def symptom_underrun(report, ui, card, isOutput, jack):
    pa_start_logging()
    p = check_test_tones(report, ui, card, isOutput, jack)
    if p is None:
       ui.information("Please try to reproduce the problem now. Close this dialog\n"
        "when the problem has appeared.")
    pa_finish_logging(report)
    report['Title'] = get_hw_title(card, isOutput, jack, "Underruns, dropouts or crackling sound")
    return p

def symptom_mixer(report, ui, card, isOutput, jack):
    pa_start_logging()
    ui.information("If there is a range of the mixer slider that's particularly\n"
        "problematic, please place the slider in that range before continuing.\n"
        "Also describe the problem in the bug report. Thank you!")
    pa_finish_logging(report)
    report['Title'] = get_hw_title(card, isOutput, jack, "volume slider problem")
    return 'alsa-base'

def symptom_user(report, ui, card, isOutput, jack):
    check_audio_users(report, ui)
    check_devices_in_use(report, ui)
    report['Title'] = get_hw_title(card, isOutput, None, "sound not working for all users")
    return 'alsa-base'
        
def symptom_no_sound(report, ui, card, isOutput, jack):
    check_volumes(report, ui, card, isOutput, jack)
    check_devices_in_use(report, ui)
    p = check_test_tones(report, ui, card, isOutput, jack)
    report['Title'] = get_hw_title(card, isOutput, jack, "No sound at all")
    return p

def symptom_fallback(report, ui, card, isOutput, jack):
    check_volumes(report, ui, card, isOutput, jack)
    p = check_test_tones(report, ui, card, isOutput, jack)
    report['Title'] = get_hw_title(card, isOutput, jack, 
        "Playback problem" if isOutput else "Recording problem")
    return 'alsa-base'

def symptom_noautomute(report, ui, card, isOutput, jack):
    check_volumes(report, ui, card, isOutput, jack)
    if jack is not None:
        ui.information("Now, please make sure the jack is NOT plugged in.\n"
            "After having done that, close this dialog.\n")
        report['Symptom_JackUnplugged'] = card.get_codecinfo()

        ui.information("Now, please plug the jack in.\n"
            "After having done that, close this dialog.\n")
        report['Symptom_JackPlugged'] = card.get_codecinfo()
    report['Title'] = get_hw_title(card, isOutput, jack, "No automute" if isOutput else "No autoswitch")
    return 'alsa-base'


def ask_symptom(report, ui, isOutput):
    ''' returns a function to call next, or StopIteration '''
    dirstr = "output" if isOutput else "input"

    symptom_map = [
        ('No sound at all', symptom_no_sound), 
        ('Only some of %ss are working' % dirstr, symptom_fallback),
        ('No auto-%s between %ss' % ("mute" if isOutput else "switch", dirstr), symptom_noautomute), 
        ('Volume slider, or mixer problems', symptom_mixer),
        ('Sound has bad quality (e g crackles, distortion, high noise levels etc)', None),
        ('Sound works for a while, then breaks', symptom_fails_after_a_while),
        ('Sound works for some users but not for others', symptom_user),
        ('None of the above', symptom_fallback)]

    symptom_badquality_map = [
        ('Digital clip or distortion, or "overdriven" sound', symptom_distortion),
        ('Underruns, dropouts, or "crackling" sound', symptom_underrun),
        ('High background noise, or volume is too low', symptom_background_noise)]
    
    problem = ui.choice('What particular problem do you observe?',
        [a for a,b in symptom_map])
    if problem is None:
        raise StopIteration
    desc, func = symptom_map[problem[0]]

    # subquestion for bad quality sound
    if func is None: 
        problem = ui.choice('In what way is the sound quality bad?',
            [a for a,b in symptom_badquality_map])
        if problem is None:
            raise StopIteration
        desc, func = symptom_badquality_map[problem[0]]

    report['Symptom_Type'] = desc
    return func


def run(report, ui):

    # is pulseaudio installed and running?
    package = check_pulseaudio_running(report, ui)
    if package is not None:
        return package

    # Hardware query
    (package, card, isOutput, jack) = ask_jack_and_card(report, ui)
    if package is not None:
        return package

    # Check that the pulseaudio profile is correctly set
    package, channelcount = check_pulseaudio_profile(report, ui, card, isOutput, jack)
    if package is not None:
        return package

    # Symptom query
    problem_func = ask_symptom(report, ui, isOutput)
    package = problem_func(report, ui, card, isOutput, jack)
    if package is not None:
        return package

    # Hopefully we don't come here, but if we do, use ALSA as fallback.
    return 'alsa-base'