2009-10-29 9 views
8

Potrzebuję stworzyć dźwięk zawierający dźwięki o różnych częstotliwościach. Czy jest jakiś sposób to zrobić w C#?Czy jest możliwe generowanie złożonych dźwięków w języku C#?

Jedyne metody generowania dźwięków, jakie dotychczas widziałem, to konsola console.beep, która działa, ale tylko dla czystych tonów (pojedynczych częstotliwości).

+0

Dla twojej informacji, używanie głośnika komputera (w przypadku sygnałów dźwiękowych) zwykle nie jest dobrą praktyką. Powinieneś użyć domyślnego wyjścia audio. – decasteljau

+0

Właściwie wolałbym używać domyślnego wyjścia audio. W końcu * będzie * potrzebna, aby przejść przez słuchawki. –

+4

To ważna kwestia. Zapomnij o dźwięku. Chcesz użyć DirectSound lub WaveOut. Oba są niezarządzanymi interfejsami API, więc musisz albo użyć PInvoke, albo przełączyć się na C++/CLI jako swój język. – CannibalSmith

Odpowiedz

19

Biblioteka Audiere czyni to niezwykle łatwe do zrobienia. Oto prawie kompletna C# program wygeneruje sygnał DTMF za pomocą przycisku „1”:

AudioDevice device = new AudioDevice(); 
OutputStream tone1a = device.CreateTone(697); // part A of DTMF for "1" button 
OutputStream tone1b = device.CreateTone(1209); // part B 
tone1a.Volume = 0.25f; 
tone1b.Volume = 0.25f; 
tone1a.Play(); 
tone1b.Play(); 
Thread.Sleep(2000); 
// when tone1a stops, you can easily tell that the tone was indeed DTMF 
tone1a.Stop(); 

Aby korzystać Audiere w C#, najprostszym sposobem, aby wstać i uruchomiony jest użycie Harald Fielker's C# binding (który twierdzi, że prace nad Mono i VS; mogę potwierdzić, że działa zarówno w pełnej wersji VS2005, jak i przy użyciu oddzielnych wersji C# i VC++ Express 2008). Musisz pobrać Win32 Audiere DLL, lib, and header (wszystkie są w tym samym pliku zip), a będziesz musiał zbudować wiązanie C# ze źródła przy użyciu zarówno VC++, jak i C#.

Jedną z zalet korzystania z Audiere jest to, że połączenia nie są blokowane. Nie musisz czekać, aż tone1a przestanie grać przed uruchomieniem tone1b, co jest oczywiście koniecznością do odtwarzania złożonych dźwięków. Nie mam informacji o żadnych twardych górnych limitach na ile równoczesnych strumieni wyjściowych można użyć, więc prawdopodobnie to, co obsługuje sprzęt/system operacyjny. Przy okazji, Audiere może również odtwarzać pewne pliki audio (MP3, WAV, AIFF, MOD, S3M, XM, IT samodzielnie, Ogg Vorbis, Flac, Speex z bibliotekami zewnętrznymi), a nie tylko czyste wygenerowane dźwięki.

Jedną z możliwych wad jest to, że po rozpoczęciu lub zatrzymaniu pojedynczego tonu słychać "kliknięcie"; nie jest to zauważalne, jeśli dodasz jeden ton do już odtwarzanego dźwięku. Najłatwiejszym sposobem na rozwiązanie tego problemu jest stopniowe zwiększanie lub zmniejszanie głośności tonów, gdy odpowiednio włączasz lub wyłączasz dźwięk. Być może będziesz musiał grać z prędkością rampy, aby uzyskać dźwięk "w sam raz".

Należy pamiętać, że Audiere ma licencję LGPL, a oprawa nie jest do niej dołączona. Będziesz musiał skonsultować się ze swoim zespołem prawnym lub spróbować zdobyć Haralda, jeśli chcesz użyć jego wiązania w produkcie komercyjnym; lub możesz po prostu stworzyć własne wiązanie i uniknąć kłopotów.


@Dom: Ponieważ nie ma konkretnej licencji dołączonej do biblioteki Haralda, nie jestem pewien, jakie będą konsekwencje jego hostowania; jednak uważam, że mogę przynajmniej podać dokładne szczegóły na temat tego, w jaki sposób został ustawiony mój projekt libaudieresharpill.

Przy użyciu Visual C++ Express 2008, otwórz bindings/csharp/libaudieresharpglue/vc8.0/libaudieresharpglue.sln. VC++ automatycznie przekonwertuje rozwiązanie na rozwiązanie VS9.

W innym folderze powinieneś mieć pakiet Audiere z Sourceforge. Pod właściwościami projektu VC++ przejdź do Właściwości konfiguracji> C/C++> Ogólne i upewnij się, że masz path/to/audiere-1.9.4-win32/include w swoich "Katalogach uwzględniania dodatkowych". Następnie, w tym samym oknie, przejdź do Linker> Ogólne i upewnij się, że masz /path/to/audiere-1.9.4-win32/lib w "Dodatkowe katalogi biblioteczne". Następnie powinieneś być w stanie zbudować projekt (najlepiej w trybie Release) i to wyjście libaudieresharpglue.dll w swoim folderze vc8.0/Release.

Następnie otwórz program Visual C# Express 2008. Otwórz pakiet bindings\csharp\test\vc8.0\AudiereCSharpTest.sln i pozwól mu go przekonwertować. Projekt powinien być dobrze zbudowany, ale wtedy pojawi się błąd, gdy go uruchomisz. W porządku; w twoim folderze csharp/test/vc8.0/bin/Release, musisz dodać zarówno libaudieresharpglue.dll z rozwiązania VC++, jak i audiere.dll z pakietu z Sourceforge.

Teraz powinieneś być w stanie zbudować i uruchomić AudiereCSharpTest. Zauważ, że domyślnie #define stream_test nie jest komentowany na górze AudiereTest.cs, a to odwołuje się do pliku, który nie znajduje się na dysku twardym. Możesz po prostu skomentować, że #define i odkomentować noise_test lub square_test.

To powinno go obejmować; jeśli przegapiłem jakieś szczegóły, mam nadzieję, że są one wystarczająco małe, aby można je było wykonać samodzielnie :)

+0

To ładnie wyglądająca biblioteka, może przyjrzeć się bliżej, jeśli NAUD nie działa dla mnie. –

+0

Mam duże problemy ze skompilowaniem części pliku "libaudieresharpglue.dll" do kompilacji. Każdy pomysł, gdzie mogę po prostu pobrać plik binarny? –

+0

Zaakceptowałem to, ponieważ jest to oczywiste, co muszę zrobić. Pomimo wyjaśnienia twojego idioty dowodu, nadal nie mogę dostać "libaudieresharpglue.dll" do kompilacji (zatrzymuje się na 100 błędach). Kiedy łączę, mówi mi, że nie może otworzyć pliku wejściowego ". \ Release \ audiere.obj" - czy jest coś elementarnego, czego mi brakuje? –

0

Tak, jest to możliwe.

Here is a link do samouczka na ten temat. ale oczywiście to również wykorzystuje Console.Beep

+0

Z tego, co tam widziałem, można generować pojedyncze dźwięki na raz. – Joey

4

Zawsze można spróbować DirectSound ...

+0

Czy masz łącze, które odnosi się w szczególności do generowania złożonych dźwięków za pomocą DirectSound? –

+2

W skrócie, zapiszesz wyniki wielu wywołań sin() w buforze fal, a potem je odtworzysz. – Kylotan

0

dokumentacji MSDN nie było jasne, czy Console.Beep jest asynchroniczne czy nie. Jeśli tak jest, prawdopodobnie możesz wystrzelić tyle połączeń, ile potrzebujesz, w krótkim odstępie czasu i nikt nie będzie mądrzejszy. Oczywiście chciałbyś użyć wersji, która wymaga częstotliwości i czasu trwania.

+0

Jest synchroniczny. – Joey

+0

Jestem nowy w C# - czy połączenia synchroniczne można nawarstwiać za pomocą wątków? –

+1

Możesz wywołać konsolę. Korzystaj z nowego wątku, ale nadal nie możesz odtwarzać wielu dźwięków jednocześnie. – twk

3

Oglądałem NAudio w celu utworzenia programu, który emuluje sprzężenie zwrotne podczas odtwarzania podkładu. Jest blog na temat generowania sine waves at specific frequencies, podejrzewam, że można go dostosować do tego, czego szukasz.

+0

To jest najbardziej obiecujące do tej pory, ale nie byłem w stanie uzyskać więcej niż jedną częstotliwość razem. –

+0

Czy próbowałeś używać wielu wątków, dokumentacja wspomina o wspieraniu urządzenia do mieszania okien. –

Powiązane problemy