Skip to content

feat: implemented the sound meter #2739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 17, 2025
Merged

Conversation

Yugesh-Kumar-S
Copy link
Collaborator

@Yugesh-Kumar-S Yugesh-Kumar-S commented Jun 13, 2025

Fixes #2738

Changes

  • Ported the sound meter instrument to flutter app.
  • Edited the InstrumentStat widget to change unit of measurement.

Screenshots / Recordings

screen-20250613-215930.mp4

Checklist:

  • No hard coding: I have used resources from strings.xml, dimens.xml and colors.xml without hard coding any value.
  • No end of file edits: No modifications done at end of resource files strings.xml, dimens.xml or colors.xml.
  • Code reformatting: I have reformatted code and fixed indentation in every file included in this pull request.
  • No extra space: My code does not contain any extra lines or extra spaces than the ones that are necessary.

Summary by Sourcery

Port the sound meter instrument to the Flutter app by integrating noise sensor data, creating new UI components for real-time and historical dB measurements, updating navigation routing, and supporting dynamic unit handling.

New Features:

  • Add real-time Sound Meter instrument including UI (SoundMeterScreen, SoundMeterCard, gauge and chart) integrated via a new route
  • Implement SoundMeterStateProvider using noise_meter to sample and aggregate decibel readings over time
  • Extend InstrumentsScreen navigation to include the sound meter view

Enhancements:

  • Parameterize Instrumentstats widget labels to use dynamic units instead of hardcoded 'Lx'
  • Introduce sound meter–specific constants (titles, units, and error messages)

Build:

  • Add noise_meter package dependency

# This is the 1st commit message:

Implemented LUX meter

# This is the commit message #2:

added const

# This is the commit message fossasia#3:

Improved responsiveness and made reusable widgets

# This is the commit message fossasia#4:

renamed file

# This is the commit message fossasia#5:

Updated view as per PSLab

# This is the commit message fossasia#6:

Implemented sound meter

# This is the commit message fossasia#7:

feat: implemented LUX meter (fossasia#2733)

fix: handled theming for instrument screens (fossasia#2732)

chore(deps): bump org.jetbrains.kotlin.android in /android

Bumps [org.jetbrains.kotlin.android](https://github.com/JetBrains/kotlin) from 1.8.22 to 2.1.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](JetBrains/kotlin@v1.8.22...v2.1.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin.android
  dependency-version: 2.1.21
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Adjusted view

Changes
@Yugesh-Kumar-S Yugesh-Kumar-S added Status: Review Required Requested reviews from peers and maintainers flutter labels Jun 13, 2025
Copy link

sourcery-ai bot commented Jun 13, 2025

Reviewer's Guide

This PR integrates a new Sound Meter feature into the Flutter app by adding a dedicated screen with a live noise data stream, chart, and gauge card, updating navigation, parameterizing existing stats widget, and introducing necessary constants and dependencies.

Sequence Diagram for Navigating to Sound Meter Screen

sequenceDiagram
    actor User
    participant InstrumentsScreen
    participant Navigator
    participant SoundMeterScreen

    User->>InstrumentsScreen: Selects Sound Meter (item 15)
    InstrumentsScreen->>Navigator: pushNamedAndRemoveUntil("/soundmeter", ...)
    Navigator->>SoundMeterScreen: Creates and displays
    SoundMeterScreen-->>User: Shows Sound Meter UI
Loading

Sequence Diagram for Sound Data Flow

sequenceDiagram
    participant UI (SoundMeterScreen)
    participant SoundMeterStateProvider
    participant NoiseMeter
    participant Timer

    activate SoundMeterStateProvider
    SoundMeterStateProvider->>NoiseMeter: Initialize & Listen for noise readings
    SoundMeterStateProvider->>Timer: Start periodic timer (e.g., every 1s)
    deactivate SoundMeterStateProvider

    loop Data Collection
        NoiseMeter-->>SoundMeterStateProvider: onData (NoiseReading)
        activate SoundMeterStateProvider
        SoundMeterStateProvider->>SoundMeterStateProvider: _currentDb = noiseReading.meanDecibel
        SoundMeterStateProvider->>SoundMeterStateProvider: notifyListeners()
        deactivate SoundMeterStateProvider
        SoundMeterStateProvider-->>UI (SoundMeterScreen): Update with new _currentDb

        Timer-->>SoundMeterStateProvider: onTick
        activate SoundMeterStateProvider
        SoundMeterStateProvider->>SoundMeterStateProvider: _currentTime = new time
        SoundMeterStateProvider->>SoundMeterStateProvider: _updateData() (updates _dbData, _timeData, dbChartData)
        SoundMeterStateProvider->>SoundMeterStateProvider: notifyListeners()
        deactivate SoundMeterStateProvider
        SoundMeterStateProvider-->>UI (SoundMeterScreen): Update chart with new dbChartData
    end
Loading

Class Diagram for SoundMeterScreen and its UI Components

classDiagram
    class SoundMeterScreen {
        +StatefulWidget
        +createState() _SoundMeterScreenState
    }
    class _SoundMeterScreenState {
        +State<SoundMeterScreen>
        +build(BuildContext context) Widget
        -_buildChartSection() Widget
        -_sideTitleWidgets(double value, TitleMeta meta) Widget
        -_buildChart(...) Widget
    }
    class SoundMeterCard {
        +StatefulWidget
        +createState() _SoundMeterCardState
    }
    class _SoundMeterCardState {
        +State<SoundMeterCard>
        +build(BuildContext context) Widget
    }
    class CommonScaffold {
        +Widget
        +String title
        +Widget body
    }
    class SoundMeterStateProvider {
        +ChangeNotifier
    }

    SoundMeterScreen --|> StatefulWidget
    _SoundMeterScreenState --|> State
    SoundMeterScreen o-- _SoundMeterScreenState : creates
    _SoundMeterScreenState "1" *-- "1" SoundMeterCard : uses
    _SoundMeterScreenState "1" *-- "1" CommonScaffold : uses
    _SoundMeterScreenState ..> SoundMeterStateProvider : consumes

    SoundMeterCard --|> StatefulWidget
    _SoundMeterCardState --|> State
    SoundMeterCard o-- _SoundMeterCardState : creates
    _SoundMeterCardState ..> SoundMeterStateProvider : consumes
Loading

Class Diagram for SoundMeterStateProvider

classDiagram
    class SoundMeterStateProvider {
        +ChangeNotifier
        -_currentDb: double
        -_noiseSubscription: StreamSubscription<NoiseReading>
        -_timeTimer: Timer
        -_dbData: List<double>
        -_timeData: List<double>
        +dbChartData: List<FlSpot>
        -_noiseMeter: NoiseMeter
        -_startTime: double
        -_currentTime: double
        -_maxLength: int
        -_dbMin: double
        -_dbMax: double
        -_dbSum: double
        -_dataCount: int
        +initializeSensors()
        +disposeSensors()
        +dispose()
        -_updateData()
        +getCurrentDb() double
        +getMinDb() double
        +getMaxDb() double
        +getAverageDb() double
        +getDbChartData() List<FlSpot>
        +getTimeInterval() double
    }
    class NoiseMeter {
        +noise: Stream<NoiseReading>
    }
    SoundMeterStateProvider --|> ChangeNotifier
    SoundMeterStateProvider ..> NoiseMeter : uses
Loading

Updated Class Diagram for Instrumentstats Widget

classDiagram
    class Instrumentstats {
        +StatelessWidget
        +String title
        +double maxValue
        +double minValue
        +double avgValue
        +String unit ## Added
        +double titleFontSize
        +double statFontSize
        +build(BuildContext context) Widget
    }
    class StatItem {
      +String label
      +dynamic value
      +double fontSize
    }
    Instrumentstats --|> StatelessWidget
    Instrumentstats "1" *-- "3" StatItem : composes >
Loading

Class Diagram for SoundMeterCard and Dependencies

classDiagram
    class SoundMeterCard {
        +StatefulWidget
    }
    class _SoundMeterCardState {
        +State<SoundMeterCard>
        +build(BuildContext context) Widget
    }
    class Instrumentstats {
        +String unit
    }
    class GaugeWidget {
        +double currentValue
        +String unit
    }
    class SoundMeterStateProvider

    SoundMeterCard o-- _SoundMeterCardState
    _SoundMeterCardState ..> SoundMeterStateProvider : uses
    _SoundMeterCardState "1" *-- "1" Instrumentstats : uses
    _SoundMeterCardState "1" *-- "1" GaugeWidget : uses
Loading

File-Level Changes

Change Details Files
Added SoundMeterScreen UI and updated navigation
  • Implemented SoundMeterScreen with MultiProvider and chart layout
  • Registered '/soundmeter' route in main.dart
  • Extended instrument navigation to handle sound meter case
lib/view/soundmeter_screen.dart
lib/main.dart
lib/view/instruments_screen.dart
Created SoundMeterStateProvider for noise streaming
  • Initialized NoiseMeter, subscribed to noise stream, and started timer
  • Buffered dB and time data, computed min/max/avg, and prepared chart spots
  • Exposed getters for current, min, max, avg, and chart data
lib/providers/soundmeter_state_provider.dart
Built SoundMeterCard with gauge and stats
  • Designed card layout combining GaugeWidget and Instrumentstats
  • Calculated responsive sizing and fetched provider values
lib/view/widgets/soundmeter_card.dart
Parameterized Instrumentstats unit display
  • Replaced hardcoded 'Lx' labels with dynamic '$unit' parameter
lib/view/widgets/instruments_stats.dart
Added sound meter constants and dependency
  • Defined error messages, unit 'dB', and title in constants.dart
  • Added noise_meter package to pubspec.yaml
lib/constants.dart
pubspec.yaml

Assessment against linked issues

Issue Objective Addressed Explanation
#2738 Maintain consistency with the existing PSLab Android app's Sound Meter behavior and visual design.
#2738 Display real-time sound level (in dB) using an interactive and visually clear gauge and line chart.
#2738 Integrate continuous audio data streaming using the device's microphone with a responsive UI that reflects changes instantly.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Yugesh-Kumar-S - I've reviewed your changes - here's some feedback:

  • Remove the embedded quotes in the danger line labelResolver (currently '"Dangerous"') so the chart label renders correctly without extra quotation marks.
  • In SoundMeterCard you’re passing the unit as a hardcoded 'dB' string—use the constants.db constant instead for consistency.
  • The Instrumentstats class name doesn’t follow Dart’s UpperCamelCase naming convention (should be InstrumentStats) – please rename it for clarity.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Remove the embedded quotes in the danger line labelResolver (currently '"Dangerous"') so the chart label renders correctly without extra quotation marks.
- In SoundMeterCard you’re passing the unit as a hardcoded 'dB' string—use the constants.db constant instead for consistency.
- The Instrumentstats class name doesn’t follow Dart’s UpperCamelCase naming convention (should be InstrumentStats) – please rename it for clarity.

## Individual Comments

### Comment 1
<location> `lib/view/widgets/soundmeter_card.dart:56` </location>
<code_context>
+                      maxValue: maxDb,
+                      minValue: minDb,
+                      avgValue: avgDb,
+                      unit: 'dB',
+                    ),
+                  ),
</code_context>

<issue_to_address>
Use the db constant instead of a string literal

Referencing the constant ensures consistency and simplifies updates if the value changes.

Suggested implementation:

```
                      unit: db,

```

Make sure that the constant `db` is defined and imported in this file. If it is not already present, you should define it (e.g., `const db = 'dB';`) or import it from the appropriate constants file.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

github-actions bot commented Jun 13, 2025

@AsCress AsCress changed the title feat: implemented the sound meter . feat: implemented the sound meter Jun 17, 2025
@AsCress AsCress enabled auto-merge (squash) June 17, 2025 15:07
@AsCress AsCress disabled auto-merge June 17, 2025 15:07
@AsCress AsCress enabled auto-merge (squash) June 17, 2025 15:09
@AsCress AsCress merged commit 545aa77 into fossasia:flutter Jun 17, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flutter Status: Review Required Requested reviews from peers and maintainers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sound Meter UI and real-time sound measurement.
3 participants