modusa 0.3.41__py3-none-any.whl → 0.3.42__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- modusa/__init__.py +1 -1
- modusa/tools/__init__.py +2 -1
- modusa/tools/audio_recorder.py +115 -0
- {modusa-0.3.41.dist-info → modusa-0.3.42.dist-info}/METADATA +2 -1
- {modusa-0.3.41.dist-info → modusa-0.3.42.dist-info}/RECORD +8 -7
- {modusa-0.3.41.dist-info → modusa-0.3.42.dist-info}/WHEEL +0 -0
- {modusa-0.3.41.dist-info → modusa-0.3.42.dist-info}/entry_points.txt +0 -0
- {modusa-0.3.41.dist-info → modusa-0.3.42.dist-info}/licenses/LICENSE.md +0 -0
    
        modusa/__init__.py
    CHANGED
    
    
    
        modusa/tools/__init__.py
    CHANGED
    
    
| @@ -0,0 +1,115 @@ | |
| 1 | 
            +
            #!/usr/bin/env python3
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #---------------------------------
         | 
| 4 | 
            +
            # Author: Ankit Anand
         | 
| 5 | 
            +
            # Date: 22/08/25
         | 
| 6 | 
            +
            # Email: ankit0.anand0@gmail.com
         | 
| 7 | 
            +
            #---------------------------------
         | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
            import sounddevice as sd
         | 
| 11 | 
            +
            import numpy as np
         | 
| 12 | 
            +
            import ipywidgets as widgets
         | 
| 13 | 
            +
            from IPython.display import display, clear_output, Audio
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            def record():
         | 
| 16 | 
            +
            	"""
         | 
| 17 | 
            +
            	Create a UI to record audio in jupyter notebook, the 
         | 
| 18 | 
            +
            	recorded signal is available as array.
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            	.. code-block:: python
         | 
| 21 | 
            +
            		
         | 
| 22 | 
            +
            		import modusa as ms
         | 
| 23 | 
            +
            		result = ms.record()
         | 
| 24 | 
            +
            		y, sr, title = result() # Keep it in the next cell
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            	Returns
         | 
| 27 | 
            +
            	-------
         | 
| 28 | 
            +
            	Callable
         | 
| 29 | 
            +
            		A lambda function that returns y(audio signal), sr(sampling rate), title(title set in the UI)
         | 
| 30 | 
            +
            	"""
         | 
| 31 | 
            +
            	devices = sd.query_devices()
         | 
| 32 | 
            +
            	device_options = [(d['name'][:30], i) for i, d in enumerate(devices) if d['max_input_channels'] > 0]
         | 
| 33 | 
            +
            	
         | 
| 34 | 
            +
            	# Controls
         | 
| 35 | 
            +
            	device_dropdown = widgets.Dropdown(
         | 
| 36 | 
            +
            		options=device_options,
         | 
| 37 | 
            +
            		description="Microphone:",
         | 
| 38 | 
            +
            		layout=widgets.Layout(width="300px")
         | 
| 39 | 
            +
            	)
         | 
| 40 | 
            +
            	
         | 
| 41 | 
            +
            	sr_dropdown = widgets.Dropdown(
         | 
| 42 | 
            +
            		options=[('16 Khz', 16000), ('22.05 Khz', 22050), ('44.1 Khz', 44100)],
         | 
| 43 | 
            +
            		value=22050,
         | 
| 44 | 
            +
            		description="Sample Rate:",
         | 
| 45 | 
            +
            		layout=widgets.Layout(width="300px")
         | 
| 46 | 
            +
            	)
         | 
| 47 | 
            +
            	
         | 
| 48 | 
            +
            	title_box = widgets.Text(
         | 
| 49 | 
            +
            		placeholder="Title",
         | 
| 50 | 
            +
            		description="Title:",
         | 
| 51 | 
            +
            		layout=widgets.Layout(width="300px")
         | 
| 52 | 
            +
            	)
         | 
| 53 | 
            +
            	
         | 
| 54 | 
            +
            	toggle_button = widgets.Button(
         | 
| 55 | 
            +
            		description="Record",
         | 
| 56 | 
            +
            		button_style="",
         | 
| 57 | 
            +
            	)
         | 
| 58 | 
            +
            	
         | 
| 59 | 
            +
            	status = widgets.HTML(value="")
         | 
| 60 | 
            +
            	out = widgets.Output()
         | 
| 61 | 
            +
            	
         | 
| 62 | 
            +
            	# State
         | 
| 63 | 
            +
            	recording = {"data": None, "sr": None, "title": None}
         | 
| 64 | 
            +
            	stream = {"obj": None, "frames": [], "recording": False}
         | 
| 65 | 
            +
            	
         | 
| 66 | 
            +
            	def callback(indata, frames, time, status):
         | 
| 67 | 
            +
            		if not status:
         | 
| 68 | 
            +
            			stream["frames"].append(indata.copy())
         | 
| 69 | 
            +
            			
         | 
| 70 | 
            +
            	def on_toggle(b):
         | 
| 71 | 
            +
            		if not stream["recording"]:
         | 
| 72 | 
            +
            			stream["frames"].clear()
         | 
| 73 | 
            +
            			sr = sr_dropdown.value
         | 
| 74 | 
            +
            			device_id = device_dropdown.value
         | 
| 75 | 
            +
            			
         | 
| 76 | 
            +
            			stream["obj"] = sd.InputStream(callback=callback, channels=1, samplerate=sr, device=device_id)
         | 
| 77 | 
            +
            			stream["obj"].start()
         | 
| 78 | 
            +
            			stream["recording"] = True
         | 
| 79 | 
            +
            			
         | 
| 80 | 
            +
            			toggle_button.description = "Stop"
         | 
| 81 | 
            +
            			toggle_button.button_style = "danger"
         | 
| 82 | 
            +
            			status.value = "Recording..."
         | 
| 83 | 
            +
            		else:
         | 
| 84 | 
            +
            			stream["obj"].stop()
         | 
| 85 | 
            +
            			stream["obj"].close()
         | 
| 86 | 
            +
            			
         | 
| 87 | 
            +
            			sr = sr_dropdown.value
         | 
| 88 | 
            +
            			y = np.concatenate(stream["frames"], axis=0).flatten()
         | 
| 89 | 
            +
            			title = title_box.value.strip() or "Recording"
         | 
| 90 | 
            +
            			
         | 
| 91 | 
            +
            			recording["data"], recording["sr"], recording["title"] = y, sr, title
         | 
| 92 | 
            +
            			record.result = (y, sr, title)
         | 
| 93 | 
            +
            			stream["recording"] = False
         | 
| 94 | 
            +
            			
         | 
| 95 | 
            +
            			toggle_button.description = "Record"
         | 
| 96 | 
            +
            			toggle_button.button_style = "success"
         | 
| 97 | 
            +
            			
         | 
| 98 | 
            +
            			with out:
         | 
| 99 | 
            +
            				clear_output()
         | 
| 100 | 
            +
            				display(Audio(y, rate=sr))
         | 
| 101 | 
            +
            				
         | 
| 102 | 
            +
            	toggle_button.on_click(on_toggle)
         | 
| 103 | 
            +
            	
         | 
| 104 | 
            +
            	# Layout
         | 
| 105 | 
            +
            	ui = widgets.VBox([
         | 
| 106 | 
            +
            		device_dropdown,
         | 
| 107 | 
            +
            		sr_dropdown,
         | 
| 108 | 
            +
            		title_box,
         | 
| 109 | 
            +
            		widgets.HBox([toggle_button]),
         | 
| 110 | 
            +
            		out
         | 
| 111 | 
            +
            	])
         | 
| 112 | 
            +
            	
         | 
| 113 | 
            +
            	display(ui)
         | 
| 114 | 
            +
            	record.result = None
         | 
| 115 | 
            +
            	return lambda: record.result
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: modusa
         | 
| 3 | 
            -
            Version: 0.3. | 
| 3 | 
            +
            Version: 0.3.42
         | 
| 4 4 | 
             
            Summary: A modular signal analysis python library.
         | 
| 5 5 | 
             
            Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
         | 
| 6 6 | 
             
            License: MIT
         | 
| @@ -10,6 +10,7 @@ Requires-Dist: matplotlib>=3.10.3 | |
| 10 10 | 
             
            Requires-Dist: yt-dlp>=2025.6.30
         | 
| 11 11 | 
             
            Requires-Dist: librosa==0.11.0
         | 
| 12 12 | 
             
            Requires-Dist: IPython>=8.0.0
         | 
| 13 | 
            +
            Requires-Dist: sounddevice>=0.5.2
         | 
| 13 14 | 
             
            Description-Content-Type: text/markdown
         | 
| 14 15 |  | 
| 15 16 | 
             
            # modusa
         | 
| @@ -1,9 +1,9 @@ | |
| 1 | 
            -
            modusa-0.3. | 
| 2 | 
            -
            modusa-0.3. | 
| 3 | 
            -
            modusa-0.3. | 
| 4 | 
            -
            modusa-0.3. | 
| 1 | 
            +
            modusa-0.3.42.dist-info/METADATA,sha256=T8MRyy7MBHjm6w1boi604AFhBgWq2zSqNYukSFB9gJw,1403
         | 
| 2 | 
            +
            modusa-0.3.42.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
         | 
| 3 | 
            +
            modusa-0.3.42.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
         | 
| 4 | 
            +
            modusa-0.3.42.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
         | 
| 5 5 | 
             
            modusa/.DS_Store,sha256=_gm6qJREwfMi8dE7n5S89_RG46u5t3xHyD-smNhtNoM,6148
         | 
| 6 | 
            -
            modusa/__init__.py,sha256= | 
| 6 | 
            +
            modusa/__init__.py,sha256=Vny15JTP5lDr_4VxA_zSqL8eARbQzqLj0dk1OBSpJmk,288
         | 
| 7 7 | 
             
            modusa/config.py,sha256=bTqK4t00FZqERVITrxW_q284aDDJAa9aMSfFknfR-oU,280
         | 
| 8 8 | 
             
            modusa/decorators.py,sha256=8zeNX_wE37O6Vp0ysR4-WCZaEL8mq8dyCF_I5DHOzks,5905
         | 
| 9 9 | 
             
            modusa/devtools/generate_docs_source.py,sha256=UDflHsk-Yh9-3YJTVBzKL32y8hcxiRgAlFEBTMiDqwM,3301
         | 
| @@ -41,11 +41,12 @@ modusa/models/t_ax.py,sha256=ZUhvZPUW1TkdZYuUd6Ucm-vsv0JqtZ9yEe3ab67Ma6w,8022 | |
| 41 41 | 
             
            modusa/models/tds.py,sha256=FAGfibjyyE_lkEuQp-vSCuqQnopOjmy_IXqUjRlg9kc,11677
         | 
| 42 42 | 
             
            modusa/plugins/__init__.py,sha256=r1Bf5mnrVKRIwxboutY1iGzDy4EPQhqpk1kSW7iJj_Q,54
         | 
| 43 43 | 
             
            modusa/plugins/base.py,sha256=Bh_1Bja7fOymFsCgwhXDbV6ys3D8muNrPwrfDrG_G_A,2382
         | 
| 44 | 
            -
            modusa/tools/__init__.py,sha256= | 
| 44 | 
            +
            modusa/tools/__init__.py,sha256=6EO3h7wMRW49ajo27BJprANPQMrOGWZudwYYRNKVISU,278
         | 
| 45 45 | 
             
            modusa/tools/ann_loader.py,sha256=RePlwD4qG6gGrD4mOJ3RDR9q_gUscCY90_R9lgFU9lM,780
         | 
| 46 46 | 
             
            modusa/tools/audio_converter.py,sha256=415qBoPm2sBIuBSI7m1XBKm0AbmVmPydIPPr-uO8D3c,1778
         | 
| 47 47 | 
             
            modusa/tools/audio_loader.py,sha256=DrCzq0pdiQrUDIG-deLJGcu8EaylO5yRtwT4lr8WSf8,2166
         | 
| 48 48 | 
             
            modusa/tools/audio_player.py,sha256=GP04TWW4jBwQBjANkfR_cJtEy7cIhvbu8RTwnf9hD6E,2817
         | 
| 49 | 
            +
            modusa/tools/audio_recorder.py,sha256=d2fVt0Sd2tlBdb2WlUs60K4N23zuxM3KUpQqX0ifPi8,2769
         | 
| 49 50 | 
             
            modusa/tools/base.py,sha256=C0ESJ0mIfjjRlAkRbSetNtMoOfS6IrHBjexRp3l_Mh4,1293
         | 
| 50 51 | 
             
            modusa/tools/math_ops.py,sha256=ZZ7U4DgqT7cOeE7_Lzi_Qq-48WYfwR9_osbZwTmE9eg,8690
         | 
| 51 52 | 
             
            modusa/tools/plotter.py,sha256=e1NKFTFm8tG7yd-9VLmxmI9h9mTcUl1vaK1XDMvyoOw,18917
         | 
| @@ -57,4 +58,4 @@ modusa/utils/excp.py,sha256=L9vhaGjKpv9viJYdmC9n5ndmk2GVbUBuFyZyhAQZmWY,906 | |
| 57 58 | 
             
            modusa/utils/logger.py,sha256=K0rsnObeNKCxlNeSnVnJeRhgfmob6riB2uyU7h3dDmA,571
         | 
| 58 59 | 
             
            modusa/utils/np_func_cat.py,sha256=TyIFgRc6bARRMDnZxlVURO5Z0I-GWhxRONYyIv-Vwxs,1007
         | 
| 59 60 | 
             
            modusa/utils/plot.py,sha256=s_vNdxvKfwxEngvJPgrF1PcmxZNnNaaXPViHWjyjJ-c,5335
         | 
| 60 | 
            -
            modusa-0.3. | 
| 61 | 
            +
            modusa-0.3.42.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |