# Audio Enhancement in Python with HANCE
HANCE is an audio enhancement engine that delivers impressive performance. With its Python wrapper, you can easily integrate HANCE into your Python projects to improve the quality of audio signals.
To learn more about HANCE, visit [Hance.ai](https://hance.ai).
## Installation
To install the Python wrapper for HANCE, use 'pip':
python -m pip install hance
HANCE is compatible with Python 3 and later.
## How to Use
The HANCE Python API is a wrapper around the C++ library.
For those eager to dive in, the examples.py script in our pythonAPI GitHub repository is the perfect starting point. This script features a command-line interface that simplifies the process of experimenting with our models. You can quickly test out various audio enhancement models without writing a single line of code. Here's how to get started:
First, clone or download the [examples.py](https://github.com/hance-engine/hance-api/blob/main/PythonAPI/examples.py) file from GitHub to your local machine.
Open your terminal or command prompt, and navigate to the directory where you downloaded the file
Execute "python examples.py" to access the command-line interface. Follow the on-screen instructions to select and run audio enhancement models.
## Using the API
To use the API, import it and list the available models:
import hance
models = hance.list_models()
print(models)
## Process a file
To process a file with HANCE, you can use the process_file function as follows:
import hance
models = hance.list_models()
hance.process_file(models[3], input_file_path, output_file_path)
This will apply the enhancement model specified by models[3] to the input file located at input_file_path, and save the enhanced audio to the output file at output_file_path. Please note that in this example, we are using PySoundFile to read and write audio files. While PySoundFile is not a requirement for using HANCE, it is a convenient library for handling audio files in Python. If you wish to use the process_file function as shown here, you will need to install PySoundFile.
## Stem Separation
For advanced audio processing, HANCE provides stem separation features. This allows you to isolate and manipulate individual components of an audio track, such as vocals, instruments, etc.
## Using StemSeparator for Advanced Stem Separation
The StemSeparator class enables more complex stem separation tasks, using multiple models for different stems. Here’s how you can use it:
import hance
import soundfile as sf
import numpy as np
import os
def separate_stems(input_file_path):
"""
Separates the stems from an input audio file using selected models with the StemSeparator class.
"""
print("Stem separation using Hance engine with StemSeparator class.")
models = ['vocals_separation.hance', 'drums_separation.hance', 'piano_separation.hance', 'bass_separation.hance']
print("Available models for separation:")
for i, model in enumerate(models):
print(f"{i+1}. {model}")
selected_models = input("Select models to use by entering their numbers separated by commas (e.g., 1,3): ")
selected_models_indices = [int(index) - 1 for index in selected_models.split(',')]
model_paths = [models[index] for index in selected_models_indices]
input_audio, sr = sf.read(input_file_path, dtype='float32')
if input_audio.ndim == 1: # Mono to Stereo if needed
input_audio = np.tile(input_audio[:, np.newaxis], (1, 2))
sample_rate = sr
num_of_channels = input_audio.ndim
engine = hance.HanceEngine()
stem_separator = engine.StemSeparator(engine.hance_engine, model_paths, num_of_channels, sample_rate)
separated_stems = stem_separator.process(input_audio)
path, fn = os.path.split(input_file_path)
for i, model_path in enumerate(model_paths):
stem_name = model_path.split('_')[0]
output_file_path = os.path.join(path, f"{fn.split('.')[0]}_{stem_name}_separated.wav")
sf.write(output_file_path, separated_stems[:, i*num_of_channels:(i+1)*num_of_channels], sr)
print(f"Stem {stem_name} saved to {output_file_path}")
print("Stem separation completed.")
separate_stems(path_to_file)
This function demonstrates how to select specific models for stem separation, process an audio file to separate the stems, and save each stem as a separate audio file.
## Process a stream
In addition to processing audio files, HANCE can also be used on audio streams in real-time. Here is an example using pyaudio to record the microphone, process it in real time, and output it to headphones.
import pyaudio
engine = hance.HanceEngine()
p = pyaudio.PyAudio()
FORMAT = pyaudio.paFloat32
CHANNELS = 1
RATE = 44100
CHUNK = 512
print("\nRecord audio from a microphone and process it in realtime with HANCE.")
print("To prevent feedback, make sure you are wearing headphones.")
print("PyAudio will induce some latency with the roundtrip to the soundcard,\nbut the HANCE engine runs in realtime.")
print("")
# Get a list of available input devices
input_devices = []
for i in range(p.get_device_count()):
device_info = p.get_device_info_by_index(i)
if device_info["maxInputChannels"] > 0:
input_devices.append(device_info)
# Print the list of available input devices and ask the user to select one
print("Available input devices:")
for i, device in enumerate(input_devices):
print(f"{i}: {device['name']}")
input_device_index = int(input("\nSelect an input device by entering its number: "))
input_device_info = input_devices[input_device_index]
# Get a list of available output devices
output_devices = []
for i in range(p.get_device_count()):
device_info = p.get_device_info_by_index(i)
if device_info["maxOutputChannels"] > 0:
output_devices.append(device_info)
# Print the list of available output devices and ask the user to select one
print("\nAvailable output devices:")
for i, device in enumerate(output_devices):
print(f"{i}: {device['name']}")
output_device_index = int(input("\nSelect an output device by entering its number: "))
output_device_info = output_devices[output_device_index]
models = hance.list_models()
processor = engine.create_processor(models[0], CHANNELS, RATE)
stop_thread = False
processor_active = True
def record_and_playback_thread():
stream_record = p.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
input_device_index=input_device_info['index'],
frames_per_buffer=CHUNK)
stream_play = p.open(format=pyaudio.paFloat32,
channels=1,
rate=RATE,
frames_per_buffer=CHUNK,
output=True,
output_device_index=output_device_info['index']
)
while not stop_thread:
data = stream_record.read(CHUNK, exception_on_overflow = False)
audio_buffer = np.frombuffer(data, dtype=np.float32)
if processor_active:
audio_buffer = processor.process(audio_buffer)
stream_play.write(audio_buffer.astype(np.float32).tobytes())
# stop Recording
stream_record.stop_stream()
stream_record.close()
stream_play.stop_stream()
stream_play.close()
t = threading.Thread(target=record_and_playback_thread)
t.start()
print("\nThe microphone and processing is active")
while True:
user_input = input("Enter 'p' to toggle processing on and off or 'x' to exit the thread: ")
if user_input.lower() == "p":
# Bypass processing and continue the loop
if processor_active:
processor_active = False
print("The processing is bypassed")
else:
processor_active = True
print("The processing is active")
elif user_input.lower() == "x":
# Stop the thread
stop_thread = True
break
t.join()
p.terminate()
For more information and examples on using HANCE, see the HANCE documentation.
Raw data
{
"_id": null,
"home_page": "https://hance.ai",
"name": "hance",
"maintainer": null,
"docs_url": null,
"requires_python": "!=2.*,>=3.0",
"maintainer_email": null,
"keywords": "hance, audio enhancement, noise reduction",
"author": "HANCE",
"author_email": "HANCE <mail@hance.ai>",
"download_url": null,
"platform": null,
"description": "# Audio Enhancement in Python with HANCE\n\nHANCE is an audio enhancement engine that delivers impressive performance. With its Python wrapper, you can easily integrate HANCE into your Python projects to improve the quality of audio signals.\n\nTo learn more about HANCE, visit [Hance.ai](https://hance.ai).\n\n## Installation\n\nTo install the Python wrapper for HANCE, use 'pip':\n\n python -m pip install hance\n\nHANCE is compatible with Python 3 and later.\n\n\n## How to Use\nThe HANCE Python API is a wrapper around the C++ library. \n\nFor those eager to dive in, the examples.py script in our pythonAPI GitHub repository is the perfect starting point. This script features a command-line interface that simplifies the process of experimenting with our models. You can quickly test out various audio enhancement models without writing a single line of code. Here's how to get started:\n\nFirst, clone or download the [examples.py](https://github.com/hance-engine/hance-api/blob/main/PythonAPI/examples.py) file from GitHub to your local machine. \n\nOpen your terminal or command prompt, and navigate to the directory where you downloaded the file\n\nExecute \"python examples.py\" to access the command-line interface. Follow the on-screen instructions to select and run audio enhancement models.\n\n\n## Using the API\nTo use the API, import it and list the available models:\n\n import hance\n models = hance.list_models()\n print(models)\n\n## Process a file\nTo process a file with HANCE, you can use the process_file function as follows:\n\n import hance\n models = hance.list_models()\n hance.process_file(models[3], input_file_path, output_file_path)\n\nThis will apply the enhancement model specified by models[3] to the input file located at input_file_path, and save the enhanced audio to the output file at output_file_path. Please note that in this example, we are using PySoundFile to read and write audio files. While PySoundFile is not a requirement for using HANCE, it is a convenient library for handling audio files in Python. If you wish to use the process_file function as shown here, you will need to install PySoundFile.\n\n## Stem Separation\nFor advanced audio processing, HANCE provides stem separation features. This allows you to isolate and manipulate individual components of an audio track, such as vocals, instruments, etc.\n\n## Using StemSeparator for Advanced Stem Separation\nThe StemSeparator class enables more complex stem separation tasks, using multiple models for different stems. Here\u2019s how you can use it:\n\n import hance\n import soundfile as sf\n import numpy as np\n import os\n\n def separate_stems(input_file_path):\n \"\"\"\n Separates the stems from an input audio file using selected models with the StemSeparator class.\n \"\"\"\n print(\"Stem separation using Hance engine with StemSeparator class.\")\n models = ['vocals_separation.hance', 'drums_separation.hance', 'piano_separation.hance', 'bass_separation.hance']\n print(\"Available models for separation:\")\n for i, model in enumerate(models):\n print(f\"{i+1}. {model}\")\n\n selected_models = input(\"Select models to use by entering their numbers separated by commas (e.g., 1,3): \")\n selected_models_indices = [int(index) - 1 for index in selected_models.split(',')]\n \n model_paths = [models[index] for index in selected_models_indices]\n\n input_audio, sr = sf.read(input_file_path, dtype='float32')\n if input_audio.ndim == 1: # Mono to Stereo if needed\n input_audio = np.tile(input_audio[:, np.newaxis], (1, 2))\n\n sample_rate = sr\n num_of_channels = input_audio.ndim\n\n engine = hance.HanceEngine()\n stem_separator = engine.StemSeparator(engine.hance_engine, model_paths, num_of_channels, sample_rate)\n \n separated_stems = stem_separator.process(input_audio)\n\n path, fn = os.path.split(input_file_path)\n for i, model_path in enumerate(model_paths):\n stem_name = model_path.split('_')[0]\n output_file_path = os.path.join(path, f\"{fn.split('.')[0]}_{stem_name}_separated.wav\")\n sf.write(output_file_path, separated_stems[:, i*num_of_channels:(i+1)*num_of_channels], sr)\n print(f\"Stem {stem_name} saved to {output_file_path}\")\n\n print(\"Stem separation completed.\")\n\n separate_stems(path_to_file)\n\nThis function demonstrates how to select specific models for stem separation, process an audio file to separate the stems, and save each stem as a separate audio file.\n\n## Process a stream\nIn addition to processing audio files, HANCE can also be used on audio streams in real-time. Here is an example using pyaudio to record the microphone, process it in real time, and output it to headphones.\n\n import pyaudio\n engine = hance.HanceEngine()\n p = pyaudio.PyAudio()\n\n FORMAT = pyaudio.paFloat32\n CHANNELS = 1\n RATE = 44100\n CHUNK = 512\n \n \n print(\"\\nRecord audio from a microphone and process it in realtime with HANCE.\")\n print(\"To prevent feedback, make sure you are wearing headphones.\")\n print(\"PyAudio will induce some latency with the roundtrip to the soundcard,\\nbut the HANCE engine runs in realtime.\")\n print(\"\")\n\n # Get a list of available input devices\n input_devices = []\n for i in range(p.get_device_count()):\n device_info = p.get_device_info_by_index(i)\n if device_info[\"maxInputChannels\"] > 0:\n input_devices.append(device_info)\n\n # Print the list of available input devices and ask the user to select one\n print(\"Available input devices:\")\n for i, device in enumerate(input_devices):\n print(f\"{i}: {device['name']}\")\n input_device_index = int(input(\"\\nSelect an input device by entering its number: \"))\n input_device_info = input_devices[input_device_index]\n\n # Get a list of available output devices\n output_devices = []\n for i in range(p.get_device_count()):\n device_info = p.get_device_info_by_index(i)\n if device_info[\"maxOutputChannels\"] > 0:\n output_devices.append(device_info)\n\n # Print the list of available output devices and ask the user to select one\n print(\"\\nAvailable output devices:\")\n for i, device in enumerate(output_devices):\n print(f\"{i}: {device['name']}\")\n output_device_index = int(input(\"\\nSelect an output device by entering its number: \"))\n output_device_info = output_devices[output_device_index]\n\n models = hance.list_models()\n processor = engine.create_processor(models[0], CHANNELS, RATE)\n \n stop_thread = False\n processor_active = True\n def record_and_playback_thread():\n stream_record = p.open(format=FORMAT, channels=CHANNELS,\n rate=RATE, input=True,\n input_device_index=input_device_info['index'],\n frames_per_buffer=CHUNK)\n \n stream_play = p.open(format=pyaudio.paFloat32,\n channels=1,\n rate=RATE,\n frames_per_buffer=CHUNK,\n output=True,\n output_device_index=output_device_info['index']\n )\n while not stop_thread:\n data = stream_record.read(CHUNK, exception_on_overflow = False)\n audio_buffer = np.frombuffer(data, dtype=np.float32)\n if processor_active:\n audio_buffer = processor.process(audio_buffer)\n stream_play.write(audio_buffer.astype(np.float32).tobytes())\n \n # stop Recording\n stream_record.stop_stream()\n stream_record.close()\n \n stream_play.stop_stream()\n stream_play.close()\n \n \n \n t = threading.Thread(target=record_and_playback_thread)\n t.start()\n \n print(\"\\nThe microphone and processing is active\")\n while True:\n user_input = input(\"Enter 'p' to toggle processing on and off or 'x' to exit the thread: \")\n if user_input.lower() == \"p\":\n # Bypass processing and continue the loop\n if processor_active:\n processor_active = False\n print(\"The processing is bypassed\")\n else:\n processor_active = True\n print(\"The processing is active\")\n elif user_input.lower() == \"x\":\n # Stop the thread\n stop_thread = True\n break\n \n t.join()\n p.terminate()\n\nFor more information and examples on using HANCE, see the HANCE documentation.\n\n",
"bugtrack_url": null,
"license": null,
"summary": "The Python API to the HANCE engine, which offers realtime audio enhancement.",
"version": "2.0.3",
"project_urls": {
"Homepage": "https://hance.ai"
},
"split_keywords": [
"hance",
" audio enhancement",
" noise reduction"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "cf7ac867560dff47483136c9c0eb047bb8a2afa512c9ca27f35525a8f6f09b88",
"md5": "b6024f31cd1d8bfc796d5f993a263a0d",
"sha256": "1ef55c8d53c02fa47b43e30d4341c656155af6474eaaeec5ecb33bcb0ce4586f"
},
"downloads": -1,
"filename": "hance-2.0.3-py3-none-macosx_10_9_x86_64.whl",
"has_sig": false,
"md5_digest": "b6024f31cd1d8bfc796d5f993a263a0d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "!=2.*,>=3.0",
"size": 26214406,
"upload_time": "2024-08-30T13:44:44",
"upload_time_iso_8601": "2024-08-30T13:44:44.114255Z",
"url": "https://files.pythonhosted.org/packages/cf/7a/c867560dff47483136c9c0eb047bb8a2afa512c9ca27f35525a8f6f09b88/hance-2.0.3-py3-none-macosx_10_9_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "9001cd1d46e166127748df6f20f992248ed444cb26720e4935f86903fd858986",
"md5": "0d621662f0eb7211f9d41004940182a0",
"sha256": "a2d26faeb228fb7c30fea651651aa4918ce89b8a3475da2659850d8067067205"
},
"downloads": -1,
"filename": "hance-2.0.3-py3-none-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "0d621662f0eb7211f9d41004940182a0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "!=2.*,>=3.0",
"size": 26214407,
"upload_time": "2024-08-30T13:44:48",
"upload_time_iso_8601": "2024-08-30T13:44:48.051178Z",
"url": "https://files.pythonhosted.org/packages/90/01/cd1d46e166127748df6f20f992248ed444cb26720e4935f86903fd858986/hance-2.0.3-py3-none-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c760238d8f7c0e6ee889cc027248504869fbfe308a7d674c8f5a28ef48c05d49",
"md5": "0766c862c96ad5e12a200adcb8e15d92",
"sha256": "d44815fdbb01f5ef3200fe72bcf3092b87b3318586e545c3942b28120e0d696b"
},
"downloads": -1,
"filename": "hance-2.0.3-py3-none-manylinux1_x86_64.whl",
"has_sig": false,
"md5_digest": "0766c862c96ad5e12a200adcb8e15d92",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "!=2.*,>=3.0",
"size": 25255308,
"upload_time": "2024-08-30T13:44:51",
"upload_time_iso_8601": "2024-08-30T13:44:51.802465Z",
"url": "https://files.pythonhosted.org/packages/c7/60/238d8f7c0e6ee889cc027248504869fbfe308a7d674c8f5a28ef48c05d49/hance-2.0.3-py3-none-manylinux1_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "577c4ff21843828d7eb5c04159de81e7aac4ad1433837ecab28537e49e79a5d5",
"md5": "07c561a0b5a8d872abd5127f6a366c60",
"sha256": "c3a225b562da7cf2345bfe982003a6352cc9088f7bae674f32a2686b24da947c"
},
"downloads": -1,
"filename": "hance-2.0.3-py3-none-win32.whl",
"has_sig": false,
"md5_digest": "07c561a0b5a8d872abd5127f6a366c60",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "!=2.*,>=3.0",
"size": 22091130,
"upload_time": "2024-08-30T13:44:55",
"upload_time_iso_8601": "2024-08-30T13:44:55.263494Z",
"url": "https://files.pythonhosted.org/packages/57/7c/4ff21843828d7eb5c04159de81e7aac4ad1433837ecab28537e49e79a5d5/hance-2.0.3-py3-none-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6f0e6c81506957734006ddf8183c271171d2bd5d5ed53e0f868984a7a779cd67",
"md5": "cf51ec8d629bd028886e310593286191",
"sha256": "f3950b27408969501d4c6e58ee11757cdd2332e4da923adcc630c334e6aa6a9b"
},
"downloads": -1,
"filename": "hance-2.0.3-py3-none-win_amd64.whl",
"has_sig": false,
"md5_digest": "cf51ec8d629bd028886e310593286191",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "!=2.*,>=3.0",
"size": 23933811,
"upload_time": "2024-08-30T13:44:58",
"upload_time_iso_8601": "2024-08-30T13:44:58.585169Z",
"url": "https://files.pythonhosted.org/packages/6f/0e/6c81506957734006ddf8183c271171d2bd5d5ed53e0f868984a7a779cd67/hance-2.0.3-py3-none-win_amd64.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-30 13:44:44",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "hance"
}