PracticU

Audio - waveOutWrite

בלי כתוביותעם כתוביות
PracticU › קורס C למתקדמים - עבודה מול חומרה Win32 › Audio - waveOutWrite
מילון מושגים:
מערך - מבנה נתונים שמאחסן אוסף ערכים מאותו סוג ברצף, שאפשר לגשת אליהם לפי מספר מיקום (אינדקס).
זיכרון - רכיב מהיר ונדיף שבו המחשב שומר נתונים ותוכניות בזמן ריצתם. תוכנו נמחק עם כיבוי המחשב.
פונקציה - קטע קוד בעל שם שמבצע משימה מוגדרת, מקבל ערכי קלט (פרמטרים) ויכול להחזיר תוצאה. מאפשרת לארגן קוד ולהשתמש בו שוב.

Audio - waveOutWrite
ההרצאה ממשיכה לניגון בפועל: בונים מאגר של בתים עם הצליל, שולחים אותו לכרטיס הקול בעזרת waveOutWrite, ומבינים מה הצליל בעצם הוא: תנודות לחץ באוויר שמזיזות את עור התוף.
איך זה עובד
1. מעבר על ההתקנים: התוכנית סופרת את ההתקנים, קוראת את השם של כל אחד, בודקת שאין שגיאה ומדפיסה אותם. המשתמש בוחר מזהה, וההרצאה בחרה 0. אחר כך מכינים את מבנה הפורמט ופותחים את ההתקן.
2. הרקע הפיזי: הרמקול מזיז את הממברנה שלו, הממברנה דוחסת את האוויר הסמוך, וכך נוצר גל לחץ שמטייל ומחליש את עצמו ככל שהוא מתרחק. כשהגל פוגע בעור התוף, המוח מתרגם את הרטט לצליל.
3. בניית המאגר: מערך של בתים בגודל 8,000, כלומר שנייה אחת בפורמט שנבחר. הערכים: 255 במשך 50 דגימות, אחר כך 0 במשך 50 דגימות, וחוזר חלילה. זה גל מרובע פשוט.
4. הכנה לפני שליחה: waveOutPrepareHeader חייבת להיקרא לפני waveOutWrite. בלי הכנה ההרצאה קיבלה את השגיאה שהכותרת לא הוכנה.
5. שליחה לניגון: waveOutWrite מעבירה את המאגר לחומרה ומחזירה מיד, והניגון מתבצע ברקע. התוכנית צריכה להמתין לפני שהיא נסגרת, כי כשהיא מסתיימת מערכת ההפעלה סוגרת את הערוץ והצליל לא נשמע.
הכותרת WAVEHDR
- WAVEHDR wh = {0}; מאפס את כל השדות. ההרצאה הסבירה שעדיף אפסים על זבל בזיכרון.
- wh.lpData = data; ו-wh.dwBufferLength = 8000; מציבים את הכתובת והאורך של המאגר.
- waveOutPrepareHeader(hwo, &wh, sizeof(WAVEHDR)); ואחריה waveOutWrite(hwo, &wh, sizeof(WAVEHDR));.
- המספר 8000 הוגדר פעם אחת כקבוע, כדי שלא יתעדכן רק בחלק מהמקומות.
שימו לב
- מערך שהוגדר כ-char רגיל מציג את הערך 255 כ-(-1) ואת 204 כ-(-52). לכן המאגר הוגדר כ-unsigned char.
- בהגדרת מבנה שדה מצביע מקבל ערך מילולי רק 0. את הכתובת הנכונה מציבים בקוד, אחרי ההגדרה.
- מבנים שנוצרים על המחסנית (stack) בתוך פונקציה נהרסים כשהפונקציה מסתיימת. בפונקציית ניגון אמיתית הכתיבה לחומרה נמשכת אחרי שהפונקציה חזרה, ולכן הנתונים צריכים להיות דינמיים (new).
בסיום ההרצאה המאגר שנבנה מנוגן דרך כרטיס הקול, והצליל המרובע נשמע.
השיעור הבא בקורס: Audio - Recording waveIn

פרקי ההרצאה: Audio - waveOutWrite

  1. 00:00

    הרצת התוכנית ובדיקת ההתקנים

  2. 00:44

    הכנת פורמט WAVE לניגון

  3. 01:24

    איך נוצר צליל: רטט וגלי לחץ

  4. 04:58

    waveOutWrite: שליחת צלילים להתקן

  5. 06:12

    מבנה WAVEHDR וטיפוסי נתונים

  6. 10:55

    איפוס מבנה ה-header לפני הניגון

  7. 13:29

    שגיאת LPSTR והצביע למידע הקול

  8. 14:43

    פוינטרים למחרוזת: מה מותר לתת

תמלול ההרצאה: Audio - waveOutWrite

הטקסט המלא של הדקות הראשונות בהרצאה «Audio - waveOutWrite» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.

  1. 00:02

    טוב, אנחנו ממשיכים בדרכנו. עם זה נקטין ונפתח את הוויז'ואל סטודיו ואודיו 0.1 יפה ואנחנו ממשיכים. טוב, אז בואו ונריץ את זה, בואו נראה מה היה לנו.

  2. 00:33

    ההרצאה הראשונה לוקחה טיפה זמן משום מה ובואו נראה. אז אנחנו אומרים לבוא את זה, אני חושב שהיה טיפה להקטין, אז אנחנו אומרים לו כמה דיווייסים יש ועוברים על הדיווייסים ועבור כל אחד מקבלים את השם בודקים שאין שגיאה מדפיסים לו יש דיווייס נגמר ואז אומרים לו אנא זה והזן ונגיד לו אפס

  3. 01:00

    ואנטר ומכינים את הווייב פורמט אקסטנדד ומזינים אותו ופונים לווייב אאוט והכל בסדר יפה. אז מה הדבר הבא? הדבר הבא מבחינתי זה right.

  4. 01:24

    בואו ננסה לכתוב לדיווייס, ממש לתת לו צלילים, לתת לו באפר עם בתים שהם ממש הצלילים. ננסה להזיז את אור התוף שלכם. דרך אגב, מה שלא הסברתי זה, כשאני מדבר על אור התוף, אז בואו רק שנייה נציג את הציור שוב.

  5. 01:47

    זה באמת אור התוף שלכם, אבל זה גם אור התוף של הרמקול, הרמקול עצמו וגם המיקרופון מה שיש שם זה אור תוף שכזה והוא מזדעזע וכשהוא מזדעזע אז הוא מזעזע את האוויר שמסביבו וזה בעצם הצלילים, הצלילים שאנחנו שומעים זה זעזועים באוויר אז כשהוא זז לפה בוא נגיד שהאוזן שלנו זה אור התוף שלנו וזה אור התוף של הרמקול וזה אור התוף שלנו.

  6. 02:24

    אז כשהוא מרטט ככה, אז כשהוא זז, אז מה הוא עושה? הוא דוחס את האוויר, נכון? בוא נגיד שיש פה מולקולות של אוויר, מרחפות באוויר, ואז הוא זז לפה. עכשיו, כשהוא זז לפה באופן פתאומי, הרי הוא זז נורא מהר, הוא זז מאות, אני חושב, או לפחות עשרות פעמים בשנייה.

  7. 02:48

    אז כשהוא זז במהירות הזו, למרות שהתנועה יחסית קטנה, עדיין זה יחסית מהר, אפילו יחסית למולקולות, ובעצם המולקולה, המולקולה שהייתה פה, הוא מזיז אותה לפה.

  8. 03:02

    הוא יוצא שכל המולקולות של מולקולות שהיו פה, פתאום הוא תול את עצמם כאן. הוא דוחף, הוא יוצר פה בעצם לחץ. האזור פה פתאום נהיה לחוץ. והלחץ הזה, כשהוא מגיע לפה, באופן טבעי, כן, הוא דוחף את המולקולה הזו לפה, אז המולקולה הזאת דוחפת את הזוטי שלידה לפה, וזוטי שלידה דוחפת את זוטי שלידה, וזוטי שלידה דוחפת...

  9. 03:30

    בקיצור, ונוצר גל של לחץ, גל הלם, שמטייל, הוא מטייל לכל הכיוונים והוא גם נחלש, לכן אם אתם מדברים עם מישהו שמדבר מרחוק אתם שומעים אותו יותר ויותר חלש ככל שזה מתרחק.

  10. 03:47

    האנרגיה שהייתה כאן מתפזרת עכשיו על כל השטח הזה, אבל הגל הזה, הגל של הלחץ מטייל ופוגע באור התוף שלכם, וכשהוא פוגע באור התוף שלכם הוא מזיז את אור התוף שלכם.

  11. 04:08

    אז יוצא מזה שהרטט ברנקול יוצא רטט בכל החדר, בכל האוויר, שמרטיט לנו את אור התוף של האוזן שלנו. וכאן יש עצם קטנה שמחוברת בסופו של דבר לתאי עצב, את העצב מרגישים את התנודה הזו והמוח מתרגם את התנודה הזו לצליל.

  12. 04:38

    איך, דרך אגב, זה זז? איך האור תוף הזה זז? על זה בהזדמנות אחרת, זה גם כן נורא נחמד ומעניין. טוב, אז אלה הם הצלילים, יפה. אז עכשיו אנחנו רוצים להשמיע צלילים.

  13. 04:58

    אז וייב אאוט רייט, מה עושה הווייב אאוט? וואי ואאוט רייט אנחנו אומרים לערוץ התקשורת לדווייס שפתחנו מה אנחנו אומרים לו אנחנו אומרים לו הנה הנה לך את זה תנגן בואו נגיד לו עכשיו זה אני חושב שזה עדיין לא יעבוד צריך להגיד לו קודם כל פריפר אבל יכול להיות שאנחנו כן נשמע משהו כבר עכשיו בואו ננסה יכול להיות שזה לא יצליח בואו ננסה צריך לתת לו את ה hw אגב אם

  14. 05:35

    אם זה שונות השם של הדבר הזה זה נקרא ל-HWO בואו נזיז את זה. אנחנו לא צריכים את הקולסטייק כרגע, בואו נשנה איפה ה-HWO הנה זה נקרא לו HWO.

  15. 05:50

    את ה-W ניקח ואת ה-O ניקח ונעשה קונטרול U ונקטין אותם אז HWO וזה HWO וזה יהיה HWO. אז מה אני אומר ל-HWO קח בבקשה את הכתובת של lp long pointer בעצם זה פוינטר מסיבות היסטוריות קוראים לו long pointer פעם היה long pointer ו-short pointer ו-far pointer ו-near pointer היו כל מיני סוגים של פוינטרים זה היה אפילו לפני זה לא לפני זמני אבל זה היה בילדות שלי ו-wave hdr נקרא לזה כן זה כתובת של wave

  16. 06:34

    header wave header שם המשתנה יהיה wave header והטיפוס שלו יהיה wave hdr אני חושב קונטרול רווח לא בדיוק בוא נגיד לו קונטרול רווח לא בדיוק מה זה היה אמור להיות תגיד לי הוא לא אומר לי תגיד לי הוא לא אומר לי קונטרול שיפט רווח ווייב hdr כן ווייב hdr למה הוא לא מזהה ווייב hdr שיפט f5 קונטרול רווח ווייב hdr אוקיי אז מה זה ווייב hdr טאג גם כן מעניין בוא נראה רגע את זה זה f12 אתם צריכים לדעת את זה

  17. 07:15

    למעשה, יכולתי להשתמש ב-Wave-Header-Tag או ב-Wave-HDA, אין הבדל. ב-C++ אין הבדל. ב-C יש הבדל. ב-C++ אתם יכולים לכתוב Struct ואת שם הטיפוס, ומעכשיו זה הטיפוס.

  18. 07:34

    זה ב-C++. ב-C אתם צריכים לכתוב את זה, Struct Wave-Header-Tag, כדי שתוכלו לדבר על הטיפוס, אתם לא יכולים לכתוב רק את זה, ולכן בשפת C מוסיפים את הטייפ דף שבעצם אומר הטיפוס הזה הטייפ דף של זה זה זה עוד על טייפ דף בהזדמנות

  19. 08:01

    אבל טייפ דף אומר הטיפוס הזה אם לא היה טייפ דף בואו נבין מה זה טייפ דף בשתי שניות מה טייפ דף אומר בואו נבין את המשפט בלי טייפ דף בלי טייפ דף כתוב פה שיש פה טיפוס מהטיפוס הזה אני מגדיר משתנה ופוינטר לטיפוס הזה זה עוד משתנה ועוד משתנה שהוא הנה ניר ניר אין לזה משמעות שהוא גם כן פוינטר ועוד משתנה

  20. 08:30

    שהוא גם כן פוינטר far אין לזה שום משמעות יפה אבל אבל אני מגדיר משתנה מסוג הטיפוס יפה זה בלי טייפ דף ואם אני כן שם טייפ דף אז מה זה אומר אז זה אומר שמסוג הטיפוס הזה אני מגדיר עוד טיפוס זה טיפוס שהוא מסוג הטיפוס הזה, וזה טיפוס שהוא מסוג מצביע לטיפוס הזה, וגם זה טיפוס שהוא מסוג מצביע לטיפוס הזה.

  21. 09:09

    זה בעזרת הטייב.דף. בקיצור, בשפת C אני יכול לכתוב את זה כשאני רוצה לדבר על טיפוס, או ב-C++ אני יכול להשתמש בזה בלי זה, ובשתיהן אני יכול להשתמש בזה אם אני שם פה טייפ דף.

  22. 09:37

    הטייפ דף וזה זה בשביל מי שכותב בשפת C, כי ההדר מתאים גם למי שעובד ב-C וגם למי שעובד ב-C++. עוד על ההבדלים ב-C ו-C++ בהזדמנות אחרת, מי שלא הבין תתעלמו, בואו נמשיך.

  23. 09:53

    מסוג וייב hdr, וייב הדר, יפה מאוד. יפה, וייב הדר, והדבר האחרון שנותן לו זה את אקאונט ביינד של וייב הדר. והסייז, סייז, סייז, בואו נגדיר את סייז, סייז אמור להיות מסוג UINT, אז נכתוב לו UINT סייז שווה לסייז אוף ווייב הדר, אני יכול דרך אגב בסייז אוף או לשים את WH או לשים את הטיפוס,

  24. 10:29

    לא משנה אם אני שם פה משתנה או טיפוס, הוא מחזיר לי את הגולל שלו, יפה מאוד. באה ומחזירה רייט, רייט מחזירה M עם ריזל, תמיד לבדוק את ה-M עם ריזל, אני אגיד ש-R שווה ואני אשכפל את השורה הזו.

  25. 10:46

    בואו נקמפל בילד, בילד סקסיד, אז זה עבד, יפה מאוד. אוקיי, השאלה היא האם נשמע משהו. שימו לב, לא עשינו שום דבר עם המשתנה הזה, אז אני לא יודע מה יקרה.

  26. 11:04

    יכול להיות שהוא סתם התפוצץ, יכול להיות שלא נשמע כלום, בואו נעשה את זה. סטפ אינטו וסטפ אובר, אובר, אובר, או שפשוט נגלול עד לנקודה הזאת, נסיר את זה, נריץ את זה, נגיד לו 0, זה enter, ואנחנו מוכנים לבצע wave out, ובואו נגיד לו step over, ובואו נראה מה נהיה, יפה מאוד, בואו ניתן לזה להציג את זה, והנה

  27. 11:32

    זה, נגיד לו את ה-rots, and invalid parameter was passed to a system function, יפה, פרמטר לא חוקי כי לא התחלנו את wave header, בואו נתחיל את wave header, אני באופן טבעי תמיד שם דבר שכזה, למה?

  28. 11:49

    כי אז אני יודע שכל השדות מאופסים. שימו לב שאם אני לא הייתי שם את זה, אז כל השדות מזובלים. בואו נראה את זה, אני שוב מריץ, ונגיד לו 0, Enter, ובואו נראה את y-inventor, ואתה רואה, הכל מלא מלא מלא בזבל.

  29. 12:07

    אני דבר ראשון אוהב, קודם כל, שהכל יהיה באפסים. עדיף לי אפסים מאשר זבל. כדי לאפס הכל, ואני אומר לו שווה ל-0. אני חושב שאני יכול גם כאן לעבור שדה שדה ולהגיד לו שהוא שווה לכל מיני ערכים, זה ל-1 וזה ל-2, אני לא יודע אם הוא יקבל את זה.

  30. 12:27

    בואו נגיד לו yes, כן, הוא מקבל את זה. בואו נריץ אותו, F5, נגיד לו 0, enter, נגיע לכאן ונראה מה הוא שם. הוא שם 0 פה, ו-1 כאן, ו-2 פה, ובכל השאר 0. זאת אומרת, ברגע שאני נותן לו 0 כאן בעצם אני אומר לו תאפס את השדה הראשון אם אני לא שם שום פרמטר בשאר השדות אז הוא מאפס את כל השאר אם אני שם ערכים הוא שם את הערכים האלה שם שימו לב שאני גם יכול להגיד לו 1 זה 2 בואו נראה אם

  31. 13:05

    הוא ייתן לי הוא לא נותן לי בואו נריט בואו נגיד לו ריסטארט אדיט יש לו שגיאה מה הבעיה אין לו שגיאה ריסטארט כנראה שיש לו שגיאה כנראה יש עינייזינג, כנראה עוד כאן דבר פרום אינט הוא lpstr, למה יש לו, ממה?

  32. 13:29

    אינט הוא lp, זה אינט והשדה אמור להיות פה lpstr, זה המעניין, נכון? קודם הוא קיבל 0, 1, 2 ועכשיו הוא לא מקבל 1, 2, למה? כי השדה הראשון כנראה היה סטרינג ואפס הוא שדה חוקי לסטרינג, בואו נראה את זה, f12 על זה, זה, זה, זה, אתם רואים? השדה הראשון הוא lpstr, פוינטר to לוק דאטה משום מה הוא משום LPSTR זה לא סטרינג זה לא מלל זה פוינטר לדאטה שלנו פה תכף נראה איך בדיוק הוציאו את זה פה יהיו

  33. 14:00

    תכף הנתונים שלנו ובינתיים הוא רואה שזה LPSTR לוק פוינטר לסטרינג בואו נסגור את כל החלונות יש פה יותר מדי דברים פתוחים על WL עושה לי את העבודה ונחזור לכאן ונצמצם הכל קולאבס טו דפינישנס וניגש לטי מיין ונגלול למטה יפה מאוד אז מה בדיוק הייתה הבעיה הבעיה היא שאני לא יכול לתת ערך לפוינטר לסטרינג

  34. 14:43

    חוץ מאשר 0 באופן כללי לפוינטרים אני לא יכול לתת ערך חוץ מאשר 0 לכל פוינטר גם לפוינטר לסטרינג אז במקרה השדה הראשון אפשר היה להזין 0 פה אם נדבר על wfx אני מקווה שזה טיפה יותר רגוע אני יכול לתת לו אחד ושתיים ושלוש בואו נשים פה breakpoint ונריץ אותו ונגיד לו אפס enter ונראה שפה

לקורס המלא: קורס C למתקדמים אונליין

ההרצאה הקודמת: Audio - waveOutOpen

ההרצאה הבאה: Audio - Recording waveIn

קורסים נוספים במסלול

  • קורס WinForms - תוכנות רגילות בווינדוס
  • פרויקט מעשי ב-#C - בונים מחשבון פשוט
  • פרויקט מעשי ב-#C - ספר טלפונים
  • פרויקט מעשי ב-#C - תוכנת צייר
  • קורס ADO.NET - חיבור אתר למסד נתונים
  • קורס תכנות מתקדם - #Advanced .NET C