diff --git a/1000-hours/public/alfred-workflows/CEPD-phonetic-transcription.alfredworkflow b/1000-hours/public/alfred-workflows/CEPD-phonetic-transcription.alfredworkflow
index 2aaa4440..1bfb284d 100644
Binary files a/1000-hours/public/alfred-workflows/CEPD-phonetic-transcription.alfredworkflow and b/1000-hours/public/alfred-workflows/CEPD-phonetic-transcription.alfredworkflow differ
diff --git a/1000-hours/public/jupyter-notebooks/8.4-daily-speech-exercises.ipynb b/1000-hours/public/jupyter-notebooks/8.4-daily-speech-exercises.ipynb
deleted file mode 100644
index c98bf455..00000000
--- a/1000-hours/public/jupyter-notebooks/8.4-daily-speech-exercises.ipynb
+++ /dev/null
@@ -1,472 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Install or update openai modules \n",
- "%pip install openai --upgrade openai \n",
- "%pip install python-dotenv mutagen pydub"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from openai import OpenAI\n",
- "import re\n",
- "import os\n",
- "import IPython\n",
- "from datetime import datetime\n",
- "from mutagen.mp3 import MP3\n",
- "from mutagen.id3 import ID3, APIC, TPE1, TALB, TCON\n",
- "from dotenv import load_dotenv\n",
- "from pydub import AudioSegment\n",
- "\n",
- "load_dotenv()\n",
- "client = OpenAI(\n",
- ")\n",
- "\n",
- "def add_metadata(mp3_file, image_file, artist, album, genre):\n",
- " try:\n",
- " audio = MP3(mp3_file, ID3=ID3)\n",
- "\n",
- " # Add ID3 tag if it doesn't exist\n",
- " try:\n",
- " audio.add_tags()\n",
- " except:\n",
- " pass\n",
- "\n",
- " # Add artist name\n",
- " audio.tags.add(TPE1(encoding=3, text=artist))\n",
- "\n",
- " # Add album name\n",
- " audio.tags.add(TALB(encoding=3, text=album))\n",
- "\n",
- " # Add genre\n",
- " audio.tags.add(TCON(encoding=3, text=genre))\n",
- "\n",
- " # Add artwork\n",
- " with open(image_file, 'rb') as albumart:\n",
- " audio.tags.add(APIC(\n",
- " encoding=3, # 3 is for utf-8\n",
- " mime='image/jpeg', # image/jpeg or image/png\n",
- " type=3, # 3 is for the cover image\n",
- " desc=u'Cover',\n",
- " data=albumart.read()\n",
- " ))\n",
- "\n",
- " audio.save()\n",
- " # print(f\"\\rMetadata added to {mp3_file}\")\n",
- "\n",
- " except Exception as e:\n",
- " print(f\"\\rAn error occurred: {e}\")\n",
- "\n",
- "def get_response(user_prompt, role_definition, model=\"gpt-4o-mini\"):\n",
- " user_prompt += \"\\n\\n Please provide response directly without further explanation.\"\n",
- "\n",
- " rspd_translation = client.chat.completions.create(\n",
- " model=model,\n",
- " messages=[\n",
- " {\n",
- " \"role\": \"system\", \n",
- " \"content\": role_definition\n",
- " },\n",
- " {\n",
- " \"role\": \"user\", \n",
- " \"content\": user_prompt\n",
- " }\n",
- " ])\n",
- " return rspd_translation.choices[0].message.content\n",
- "\n",
- "def get_openai_tts_audio(text, file_name=\"\", performer=\"alloy\", silence_duration=1500, with_ending=False, ending_file=\"resources/ending.mp3\", progress=True):\n",
- "\n",
- " # check artwork.png and ending.mp3 files exist\n",
- " if not os.path.isfile('resources/Artwork.png') or not os.path.isfile('resources/ending.mp3'):\n",
- " print(\"\\rEither Artwork.png or ending.mp3 file not found.\")\n",
- " return\n",
- "\n",
- " # split the text into lines\n",
- " text = markdown_to_text(text).split(\"\\n\")\n",
- " # remove empty lines\n",
- " text = [t for t in text if t]\n",
- "\n",
- " for t in text:\n",
- " speech_file_path = f'temp-{text.index(t)}.mp3'\n",
- " \n",
- " with client.audio.speech.with_streaming_response.create(\n",
- " model=\"tts-1\",\n",
- " voice=performer,\n",
- " input=t.strip()\n",
- " ) as response:\n",
- " response.stream_to_file(speech_file_path)\n",
- " \n",
- " # output a progress percentage, keep updating within a line\n",
- " if progress:\n",
- " print(f\"\\rprocessing audio performed by {performer.capitalize()}: {round((text.index(t)+1)/len(text)*100)}%\", end='...')\n",
- " if progress:\n",
- " print(\"\\n\")\n",
- " \n",
- " # create an audio of silence of specified silence_duration\n",
- " temp_audio = AudioSegment.silent(duration=silence_duration)\n",
- " for t in text:\n",
- " seg = AudioSegment.from_file(f'temp-{text.index(t)}.mp3')\n",
- " temp_audio += seg + AudioSegment.silent(duration=silence_duration)\n",
- " # delete the temp file\n",
- " os.remove(f'temp-{text.index(t)}.mp3')\n",
- " temp_audio.export('~temp.mp3', format='mp3')\n",
- " speech = AudioSegment.from_file('~temp.mp3')\n",
- " if with_ending:\n",
- " ending = AudioSegment.from_file(ending_file)\n",
- " combined = speech + ending\n",
- " else:\n",
- " combined = speech\n",
- " os.remove('~temp.mp3')\n",
- " if file_name:\n",
- " # if file_name has no extension, add .mp3\n",
- " if file_name.endswith('.mp3'):\n",
- " speech_file_path = file_name\n",
- " else:\n",
- " speech_file_path = f'{file_name}.mp3' \n",
- " else:\n",
- " speech_file_path = f'{datetime.now().strftime(\"%Y%m%d_%H%M%S\")}_{performer}.mp3'\n",
- " combined.export(speech_file_path, format='mp3')\n",
- " # print(f\"\\rAudio file saved as {speech_file_path}\")\n",
- "\n",
- " image_file = 'resources/Artwork.png'\n",
- " artist = 'tts'\n",
- " album = 'Daily Speech Training'\n",
- " genre = 'SPEECH'\n",
- "\n",
- " add_metadata(speech_file_path, image_file, artist, album, genre)\n",
- " IPython.display.Audio(speech_file_path)\n",
- "\n",
- " return speech_file_path\n",
- "\n",
- "# convert markdown to plain text\n",
- "def markdown_to_text(markdown_text):\n",
- " # remove bold text\n",
- " text = re.sub(r'\\*\\*(.*?)\\*\\*', r'\\1', markdown_text)\n",
- " # remove italic text\n",
- " text = re.sub(r'\\*(.*?)\\*', r'\\1', text)\n",
- " # remove links\n",
- " text = re.sub(r'\\[(.*?)\\]\\(.*?\\)', r'\\1', text)\n",
- " # remove images\n",
- " text = re.sub(r'\\!\\[.*?\\]\\(.*?\\)', '', text)\n",
- " # remove code blocks\n",
- " text = re.sub(r'```(.*?)```', r'\\1', text)\n",
- " # remove inline code\n",
- " text = re.sub(r'`(.*?)`', r'\\1', text)\n",
- " # remove ordered lists\n",
- " text = re.sub(r'\\d+\\.(.*?\\n)', r'\\1', text)\n",
- " # remove unordered lists\n",
- " text = re.sub(r'\\*(.*?\\n)', r'\\1', text)\n",
- " # remove blockquotes\n",
- " text = re.sub(r'>(.*?\\n)', r'\\1', text)\n",
- " # remove horizontal rules\n",
- " text = re.sub(r'-+', '', text)\n",
- " # remove headings\n",
- " text = re.sub(r'#+', '', text)\n",
- " # remove extra spaces\n",
- " text = re.sub(r' +', ' ', text)\n",
- " text = text.strip()\n",
- " return text\n",
- "\n",
- "def add_zero(number, length=2):\n",
- " return str(number).zfill(length)\n",
- "\n",
- "# read text from a file\n",
- "def read_text_from_file(file_path):\n",
- " with open(file_path, 'r') as file:\n",
- " return file.read()\n",
- " \n",
- "# write text to a file\n",
- "def write_text_to_file(file_path, text):\n",
- " with open(file_path, \"w\") as file:\n",
- " file.write(text)\n",
- "\n",
- "# read lines from a file\n",
- "def read_lines_from_file(file_path):\n",
- " with open(file_path, 'r') as file:\n",
- " return file.readlines()\n",
- "\n",
- "# write lines to a file\n",
- "def write_lines_to_file(file_path, lines):\n",
- " with open(file_path, 'w') as file:\n",
- " file.writelines(lines)\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Mastering a skill is much like honing a craft with a chisel: learning provides the foundational knowledge, but it is practice that shapes the masterpiece. In a world where knowledge is at our fingertips, the danger lies not in a lack of information, but in our failure to translate that information into action. Learning is an essential first step, akin to gathering the raw materials needed for a project; however, it is through rigorous practice that we refine those materials into something meaningful.\n",
- "\n",
- "Think about it this way: learning serves as our intellectual toolbox, while practice is the actual construction work. When we engage in practical application, we’re not merely reviewing what we've learned; we’re embedding those ideas into our very being, making them second nature. This transformation is what separates the novices from the experts. For instance, a musician can study music theory for years, but without consistent practice, those notes on a page remain just that — notes on a page.\n",
- "\n",
- "The overwhelming majority of people who claim that what they learn is not useful may simply be overlooking the fact that they haven't put in the necessary time to practice. When knowledge remains dormant, it cannot spark creativity or innovation; thus, the notion that learning is inadequate becomes a self-fulfilling prophecy. Engaging in regular, deliberate practice bridges the gap between book smarts and street smarts.\n",
- "\n",
- "In the end, the most profound lessons often come from doing more than just thinking. To truly embody what we've learned, we must grab life by the reins and dive headfirst into practice. In this dance between learning and practicing, it is practice that ultimately leads to mastery, making it the unsung hero in the journey toward expertise.\n",
- "\n",
- "Generating the audio file...\n",
- "\n",
- "processing audio performed by Alloy: 100%...\n",
- "\n",
- "Audio file saved as Discourse_learning-and_20240823_091917-alloy.mp3!\n",
- "\n",
- "processing audio performed by Nova: 100%...\n",
- "\n",
- "Audio file saved as Discourse_learning-and_20240823_091917-nova.mp3!\n",
- "\n",
- "All done!\n"
- ]
- }
- ],
- "source": [
- "# Generate a passage by ChatGPT, with topic, key words or points you specify.\n",
- "\n",
- "role_definition = \"\"\"\n",
- "You're my American English guru, \n",
- "Whatever topic or key words or points I give you,\n",
- "You'll develop them into a 300 words American English essay.\n",
- "Be creative, do not use any cliche to start your passage, such as \"In todays's fast-paced world\"...\n",
- "If I send you \"random\", you'll write a random essay with recent events or trending topics.\n",
- "Use as diverse as possible expressions or idioms Americans use in daily conversations.\n",
- "Return the passage as pure text without any markdown or code block.\n",
- "\"\"\"\n",
- "\n",
- "user_prompt = \"\"\"\n",
- "learning and practicing\n",
- "\n",
- "学本身用处并不大的,练才是真正的关键。学只不过是知道,只有高密度地练才能做到。\n",
- "\n",
- "学是系统二的工作。练是把知识、技能、流程和习惯压缩进系统一的工作。\n",
- "\n",
- "如果学的重要性是 1 的话,练的重要性可能是 99 甚至 9999。\n",
- "\n",
- "学是为了练,练是为了把学变成自己的东西。\n",
- "\n",
- "学了很多很多,从来不练,才是人们最大的问题。说什么学到的东西用不上,只不过是自己没练所以才用不了而已。哪儿有什么学了没用的东西呢?\n",
- "\"\"\"\n",
- "\n",
- "rspd = get_response(user_prompt, role_definition, model=\"gpt-4o-mini\")\n",
- "rspd = rspd.replace(\"—\", \" — \")\n",
- "\n",
- "audio_filename_prefix = f\"Discourse_{'-'.join(user_prompt.strip().rstrip(',.!?\\\")').split(' ')[:2])}_{datetime.now().strftime('%Y%m%d_%H%M%S')}\"\n",
- "\n",
- "print(rspd + \"\\n\\nGenerating the audio file...\\n\")\n",
- "write_text_to_file(f'{audio_filename_prefix}.md', rspd)\n",
- "\n",
- "for p in [\"alloy\", \"nova\"]:\n",
- " audio_filename = get_openai_tts_audio(rspd, file_name=f'{audio_filename_prefix}-{p}.mp3', performer=p, silence_duration=1500, with_ending=True, ending_file=\"ending.mp3\")\n",
- " print(f\"Audio file saved as {audio_filename_prefix}-{p}.mp3!\\n\")\n",
- "\n",
- "print(\"All done!\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\n",
- "Conversation 1: The Balance Between Learning and Practicing\n",
- "Alloy: You know, I believe that practicing is way more important than just learning.\n",
- "Nova: That's an interesting take! But can we really downplay the importance of learning?\n",
- "Alloy: Not entirely, but I think learning is just the starting point. Practice is where it counts.\n",
- "Nova: I get that. It's like the old saying, 'you can lead a horse to water, but you can't make it drink.'\n",
- "Alloy: Exactly! Just sitting in a classroom won't make you a pro. You’ve got to roll up your sleeves.\n",
- "Nova: I agree, but don’t you think some foundational knowledge is necessary before you can even practice?\n",
- "Alloy: Sure, but too much focus on learning can lead to overthinking. You just have to dive in!\n",
- "Nova: That's a fair point. People often get stuck in analysis paralysis. But what about the risk of learning the wrong way?\n",
- "Alloy: That’s where good mentorship comes in. They can guide your practice and correct any mistakes.\n",
- "Nova: Valid argument! Perhaps the blend of learning and practicing is more about ratios rather than strict hierarchy.\n",
- "\n",
- "Conversation 2: Understanding the Role of Learning vs. Practicing\n",
- "Alloy: Have you ever noticed how some people just learn and never really practice? It's puzzling.\n",
- "Nova: Oh, for sure. It’s like they think just knowing something is enough. But that's not how it works!\n",
- "Alloy: Exactly! Knowledge without application is like having a key that doesn't fit any lock.\n",
- "Nova: Ha! Good analogy! But what about folks who claim they learned a lot yet can't apply it?\n",
- "Alloy: I think they’re just making excuses. If you really grasp something, practicing it should come naturally.\n",
- "Nova: But there are always exceptions. Some people might need more time to process before taking action.\n",
- "Alloy: That could be, but there's a line between understanding and overthinking, don’t you think?\n",
- "Nova: Absolutely! It’s frustrating when you see someone stuck in their own head.\n",
- "Alloy: At the end of the day, practice solidifies what you've learned, turning knowledge into skill.\n",
- "Nova: True that! I guess it’s all about finding that sweet spot between learning and practicing.\n",
- "\n",
- "Generating the audio file...\n",
- "\n",
- "Audio file saved as Conversation_learning-and_20240823_092956.mp3!\n"
- ]
- },
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Generating audio from conversations with a topic you specify.\n",
- "\n",
- "import json\n",
- "import random\n",
- "\n",
- "def conversation_audio(conversation):\n",
- " topic = conversation['topic'].strip()\n",
- " random_speaker = [\"Alloy\", \"Nova\"][random.randint(0, 1)].lower()\n",
- " # 1 second silence audio\n",
- " audio = AudioSegment.silent(duration=500)\n",
- " topic_audio = AudioSegment.from_file(get_openai_tts_audio(topic, \"temp~~.mp3\", random_speaker, 1000, with_ending=False, progress=False))\n",
- " audio += topic_audio\n",
- " # remove topic.mp3 file\n",
- " os.remove(\"temp~~.mp3\")\n",
- " sounds = [\"resources/Basso.aiff\", \"resources/Blow.aiff\", \"resources/Bottle.aiff\", \"resources/Frog.aiff\", \"resources/Funk.aiff\", \"resources/Glass.aiff\", \"resources/Hero.aiff\", \"resources/Morse.aiff\", \"resources/Ping.aiff\", \"resources/Pop.aiff\", \"resources/Purr.aiff\", \"resources/Sosumi.aiff\", \"resources/Submarine.aiff\", \"resources/Tink.aiff\"]\n",
- " sound = random.choice(sounds)\n",
- " AudioSegment.from_file(sound).export(\"dot-ending.mp3\", format=\"mp3\")\n",
- " ending_file_name = \"dot-ending.mp3\"\n",
- "\n",
- " for exchange in conversation['exchanges']:\n",
- " for speaker, line in exchange.items():\n",
- " # if last line in exchange, assign with_ending=True\n",
- " with_ending = conversation['exchanges'].index(exchange) == len(conversation['exchanges']) - 1\n",
- " # print(f\"\\rspeaker, line, with_ending\")\n",
- " audio += AudioSegment.from_file(get_openai_tts_audio(line.replace(\"—\", \" — \"), \"temp~~.mp3\", speaker.lower(), 1000, with_ending, ending_file=ending_file_name, progress=False))\n",
- " # remove temp file\n",
- " os.remove(\"temp~~.mp3\")\n",
- "\n",
- " os.remove(ending_file_name)\n",
- "\n",
- " return audio\n",
- "\n",
- "# user_prompt = \"\"\"\n",
- "# on homosexuality, Although we don't oppose homosexuality, we do have another concern—what if our child isn't naturally homosexual but is somehow influenced to become one? How should we view this situation, and how can we prevent it from happening?\n",
- "# \"\"\"\n",
- "\n",
- "role_definition = \"\"\"\n",
- "You're my American English guru, \n",
- "Whatever topic or key words I give you,\n",
- "You'll desing two conversations or debates with several exchanges between Alloy and Nova,\n",
- "each of which is about 400 words long, and is completely different with each other.\n",
- "Make sure to mix exchnages in conversation with positive, neutral, and negative reactions, which might well including specifically from: \n",
- "agreement, enthusiasm, support, admiration, acknowledgment, curiosity, clarification, reflection, disagreement, doubt, surprise, disapproval, confusion, indifference, frustration, sarcasm, etc.\n",
- "Be creative to start every exchanges in conversation.\n",
- "Use as diverse as possible expressions or idioms Americans use in daily conversations.\n",
- "Return these conversations in json format, without code block such as ```json```.\n",
- "Check the validity of the json format before returning it.\n",
- "\n",
- "Example of a conversation:\n",
- "\n",
- "{\n",
- " \"conversations\": [\n",
- " {\n",
- " \"topic\": \"The Importance of Renewable Energy\",\n",
- " \"exchanges\": [\n",
- " {\n",
- " \"Alloy\": \"I really think we should invest more in renewable energy sources.\"\n",
- " },\n",
- " {\n",
- " \"Nova\": \"I agree, but do you think it's feasible for all countries right now?\"\n",
- " },\n",
- " {\n",
- " \"Alloy\": \"Definitely! With the right policies and technological advancements, it can be achieved.\"\n",
- " },\n",
- " {\n",
- " \"Nova\": \"True, but the initial costs might be a hurdle for some developing nations.\"\n",
- " },\n",
- " {\n",
- " \"Alloy\": \"That's valid. Perhaps international support could help bridge that gap.\"\n",
- " }\n",
- " ]\n",
- " },\n",
- " ],\n",
- "}\n",
- "\"\"\"\n",
- "\n",
- "responds = get_response(user_prompt, role_definition, model=\"gpt-4o-mini\")\n",
- "\n",
- "# load json\n",
- "conversations = json.loads(responds)\n",
- "\n",
- "# extract first three words from the user prompt to use as the filename prefix\n",
- "whole_audio_filename_prefix = f\"Conversation_{'-'.join(user_prompt.strip().rstrip(',.!?\\\")').split(' ')[:2])}_{datetime.now().strftime('%Y%m%d_%H%M%S')}\"\n",
- "\n",
- "# dump json to a file\n",
- "with open(f\"{whole_audio_filename_prefix}.json\", \"w\") as file:\n",
- " json.dump(conversations, file)\n",
- "\n",
- "# get each conversation, topic and exchanges, and each exchange\n",
- "with open(f\"{whole_audio_filename_prefix}.md\", \"w\") as file:\n",
- " for conversation in conversations['conversations']:\n",
- " topic = conversation['topic']\n",
- " exchanges = conversation['exchanges']\n",
- " print(f\"\\nConversation {conversations['conversations'].index(conversation)+1}: {topic}\")\n",
- " file.write(f\"\\n## Conversation {conversations['conversations'].index(conversation)+1}: {topic}\\n\")\n",
- " for exchange in exchanges:\n",
- " for speaker, text in exchange.items():\n",
- " print(f\"{speaker}: {text}\")\n",
- " file.write(f\"\\n**{speaker}**: {text.replace(\"—\", \" — \")}\\n\")\n",
- "\n",
- "print(\"\\nGenerating the audio file...\")\n",
- "whole_audio = AudioSegment.silent(duration=1000)\n",
- "# get each conversation, topic and exchanges, and each exchange\n",
- "for conversation in conversations['conversations']:\n",
- " whole_audio += conversation_audio(conversation)\n",
- "\n",
- "whole_audio += AudioSegment.from_file(\"resources/ending.mp3\")\n",
- "whole_audio_filename = f\"{whole_audio_filename_prefix}.mp3\"\n",
- "whole_audio.export(whole_audio_filename, format=\"mp3\")\n",
- " \n",
- "add_metadata(whole_audio_filename, 'Artwork.png', 'tts', 'Daily Speech Training - Conversations', 'SPEECH')\n",
- "print(f\"\\nAudio file saved as {whole_audio_filename}!\") \n",
- "IPython.display.Audio(whole_audio_filename)"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "base",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.12.2"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/1000-hours/public/jupyter-notebooks/8.4-daily-speech-exercises.zip b/1000-hours/public/jupyter-notebooks/8.4-daily-speech-exercises.zip
index 3dd68f5b..d88d6bfd 100644
Binary files a/1000-hours/public/jupyter-notebooks/8.4-daily-speech-exercises.zip and b/1000-hours/public/jupyter-notebooks/8.4-daily-speech-exercises.zip differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Artwork.png b/1000-hours/public/jupyter-notebooks/resources/Artwork.png
deleted file mode 100644
index 8ae4e581..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Artwork.png and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Basso.aiff b/1000-hours/public/jupyter-notebooks/resources/Basso.aiff
deleted file mode 100644
index e2cf1cdf..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Basso.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Blow.aiff b/1000-hours/public/jupyter-notebooks/resources/Blow.aiff
deleted file mode 100644
index d91a572d..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Blow.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Bottle.aiff b/1000-hours/public/jupyter-notebooks/resources/Bottle.aiff
deleted file mode 100644
index b9f92afc..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Bottle.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Frog.aiff b/1000-hours/public/jupyter-notebooks/resources/Frog.aiff
deleted file mode 100644
index 86fb39da..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Frog.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Funk.aiff b/1000-hours/public/jupyter-notebooks/resources/Funk.aiff
deleted file mode 100644
index 4be05108..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Funk.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Glass.aiff b/1000-hours/public/jupyter-notebooks/resources/Glass.aiff
deleted file mode 100644
index e07aeed9..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Glass.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Hero.aiff b/1000-hours/public/jupyter-notebooks/resources/Hero.aiff
deleted file mode 100644
index bd371ab8..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Hero.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Morse.aiff b/1000-hours/public/jupyter-notebooks/resources/Morse.aiff
deleted file mode 100644
index fa21a269..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Morse.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Ping.aiff b/1000-hours/public/jupyter-notebooks/resources/Ping.aiff
deleted file mode 100644
index 4d29f10e..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Ping.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Pop.aiff b/1000-hours/public/jupyter-notebooks/resources/Pop.aiff
deleted file mode 100644
index 9700859d..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Pop.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Purr.aiff b/1000-hours/public/jupyter-notebooks/resources/Purr.aiff
deleted file mode 100644
index 3f9ea306..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Purr.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Sosumi.aiff b/1000-hours/public/jupyter-notebooks/resources/Sosumi.aiff
deleted file mode 100644
index 5b6bf16e..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Sosumi.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Submarine.aiff b/1000-hours/public/jupyter-notebooks/resources/Submarine.aiff
deleted file mode 100644
index 2e2ee188..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Submarine.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/Tink.aiff b/1000-hours/public/jupyter-notebooks/resources/Tink.aiff
deleted file mode 100644
index 6b413aa6..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/Tink.aiff and /dev/null differ
diff --git a/1000-hours/public/jupyter-notebooks/resources/ending.mp3 b/1000-hours/public/jupyter-notebooks/resources/ending.mp3
deleted file mode 100644
index 27567f76..00000000
Binary files a/1000-hours/public/jupyter-notebooks/resources/ending.mp3 and /dev/null differ
diff --git a/1000-hours/sounds-of-american-english/8.2-cepd-phonetics-and-sound.md b/1000-hours/sounds-of-american-english/8.2-cepd-phonetics-and-sound.md
index 1144e33c..c8461d49 100644
--- a/1000-hours/sounds-of-american-english/8.2-cepd-phonetics-and-sound.md
+++ b/1000-hours/sounds-of-american-english/8.2-cepd-phonetics-and-sound.md
@@ -21,7 +21,7 @@
> * `cams`:查询音标(美式发音)
> * `camk`:查询音标(英式发音)
> * `camsd`:用浏览器打开 CEPD 真人示范录音(美式发音)在线网址
-> * `camsd`:用浏览器打开 CEPD 真人示范录音(英式发音)在线网址
+> * `camkd`:用浏览器打开 CEPD 真人示范录音(英式发音)在线网址
> * `camw`:用浏览器打开 CEPD 查询页面
> * `ipa`:返回 CMU(卡耐基梅隆大学)音标库中的音标
@@ -102,4 +102,4 @@ for p in phonetics:
returnvalue += p + ' '
sys.stdout.write(returnvalue.strip())
-```
\ No newline at end of file
+```